diff --git a/src/H5D.c b/src/H5D.c
index b97d7597c2..865a7327c5 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -33,7 +33,6 @@
  */
 #include "H5FDmpio.h"
 
-
 #ifdef H5_HAVE_PARALLEL
 /* Remove this if H5R_DATASET_REGION is no longer used in this file */
 #   include "H5Rpublic.h"
diff --git a/src/H5F.c b/src/H5F.c
index 5c457b74dc..b98eae89d9 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -39,7 +39,7 @@
 #include "H5Iprivate.h"		/*object IDs				  */
 #include "H5ACprivate.h"	/*cache					  */
 #include "H5Eprivate.h"		/*error handling			  */
-#include "H5Fpkg.h"         /*file access                             */
+#include "H5Fpkg.h"             /*file access                             */
 #include "H5FDprivate.h"	/*file driver				  */
 #include "H5Gprivate.h"		/*symbol tables				  */
 #include "H5MMprivate.h"	/*core memory management		  */
@@ -53,13 +53,28 @@ static int interface_initialize_g = 0;
 #define INTERFACE_INIT H5F_init_interface
 static herr_t H5F_init_interface(void);
 
+/* Struct only used by functions H5F_get_objects and H5F_get_objects_cb */
+typedef struct H5F_olist_t {
+    H5I_type_t obj_type;
+    hid_t      *obj_id_list;
+    unsigned   *obj_id_count;
+    H5F_file_t *shared;
+    unsigned   list_index;
+} H5F_olist_t;    
+
 /* PRIVATE PROTOTYPES */
 static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id);
 static herr_t H5F_dest(H5F_t *f);
 static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
 			hbool_t alloc_only);
 static haddr_t H5F_locate_signature(H5FD_t *file);
-static int H5F_flush_all_cb(H5F_t *f, const void *_invalidate);
+static int H5F_flush_all_cb(H5F_t *f, hid_t fid, const void *_invalidate);
+static herr_t H5F_get_obj_count(H5F_t *f, unsigned types, 
+				unsigned *obj_id_count); 
+static herr_t H5F_get_obj_ids(H5F_t *f, unsigned types, hid_t *obj_id_list);
+static herr_t H5F_get_objects(H5F_t *f, unsigned types, hid_t *obj_id_list, 
+				unsigned *obj_id_count);
+static herr_t H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
 
 /* Declare a free list to manage the H5F_t struct */
 H5FL_DEFINE_STATIC(H5F_t);
@@ -184,6 +199,8 @@ H5F_init_interface(void)
     unsigned        gc_ref              = H5F_ACS_GARBG_COLCT_REF_DEF;
     hid_t           driver_id           = H5F_ACS_FILE_DRV_ID_DEF;
     void            *driver_info        = H5F_ACS_FILE_DRV_INFO_DEF;
+    H5F_close_degree_t close_degree     = H5F_CLOSE_DEGREE_DEF;
+
     /* File mount property class variable. 
      * - Mount property class to modify
      * - whether absolute symlinks is local to file 
@@ -356,6 +373,11 @@ H5F_init_interface(void)
         /* Register the file driver info */
         if(H5P_register(acs_pclass,H5F_ACS_FILE_DRV_INFO_NAME,H5F_ACS_FILE_DRV_INFO_SIZE, &driver_info,NULL,NULL,NULL,NULL,NULL,NULL)<0) 
              HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
+
+        /* Register the file close degree */
+        if(H5P_register(acs_pclass,H5F_CLOSE_DEGREE_NAME,H5F_CLOSE_DEGREE_SIZE, &close_degree,NULL,NULL,NULL,NULL,NULL,NULL)<0)
+             HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
+
     } /* end if */
 
     /* Only register the default property list if it hasn't been created yet */
@@ -610,7 +632,7 @@ done:
  *-------------------------------------------------------------------------
  */
 static int
-H5F_flush_all_cb(H5F_t *f, const void *_invalidate)
+H5F_flush_all_cb(H5F_t *f, hid_t fid, const void *_invalidate)
 {
     hbool_t	invalidate = *((const hbool_t*)_invalidate);
     H5F_flush(f, H5F_SCOPE_LOCAL, invalidate, FALSE);
@@ -788,7 +810,8 @@ H5Fget_access_plist(hid_t file_id)
     H5P_genplist_t *new_plist;              /* New property list */
     H5P_genplist_t *old_plist;              /* Old property list */
     hid_t		ret_value = SUCCEED;
-    
+    void		*driver_info=NULL;   
+ 
     FUNC_ENTER(H5Fget_access_plist, FAIL);
     H5TRACE1("i","i",file_id);
 
@@ -828,13 +851,292 @@ H5Fget_access_plist(hid_t file_id)
 
     if(H5P_set(new_plist, H5F_ACS_FILE_DRV_ID_NAME, &(f->shared->lf->driver_id)) < 0)
         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver ID");
-    if(H5P_set(new_plist, H5F_ACS_FILE_DRV_INFO_NAME, H5FD_fapl_get(f->shared->lf)) < 0)
+
+    driver_info = H5FD_fapl_get(f->shared->lf);
+    if(driver_info != NULL && H5P_set(new_plist, H5F_ACS_FILE_DRV_INFO_NAME, driver_info) < 0)
         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver info");
 
+    if(f->shared->fc_degree == H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_CLOSE_DEGREE_NAME, &(f->shared->lf->cls->fc_degree)) < 0) {
+        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree"); 
+    } else if(f->shared->fc_degree != H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_CLOSE_DEGREE_NAME, &(f->shared->fc_degree)) < 0) {
+        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree");   
+    } 
+
 done:
     FUNC_LEAVE(ret_value);
 }
 
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Fget_obj_count
+ *
+ * Purpose:	Public function returning the number of opened object IDs 
+ *		(files, datasets, groups and datatypes) in the same file. 
+ *
+ * Return:	Non-negative on success; negative on failure.
+ * 
+ * Programmer:	Raymond Lu
+ *		Wednesday, Dec 5, 2001
+ *
+ * Modification:
+ *	
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fget_obj_count(hid_t file_id, unsigned types, unsigned *obj_id_count)
+{
+    H5F_t    *f=NULL;
+    herr_t   ret_value = SUCCEED;
+
+    FUNC_ENTER(H5Fget_obj_counts, FAIL);
+    H5TRACE3("e","iIu*Iu",file_id,types,obj_id_count);
+
+    if( file_id != H5F_OBJ_ALL && (H5I_FILE != H5I_get_type(file_id) || 
+        NULL==(f=H5I_object(file_id))) )
+        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id");
+    if( (types&H5F_OBJ_ALL)==0)
+        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type");
+    assert(obj_id_count);
+
+    ret_value = H5F_get_obj_count(f, types, obj_id_count);
+
+done:
+    FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:    H5F_get_obj_count
+ *
+ * Purpose:	Private function return the number of opened object IDs
+ *		(files, datasets, groups, datatypes) in the same file.
+ *
+ * Return:      Non-negative on success; negative on failure.
+ *
+ * Programmer:  Raymond Lu
+ *              Wednesday, Dec 5, 2001
+ *
+ * Modification:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_get_obj_count(H5F_t *f, unsigned types, unsigned *obj_id_count)
+{
+    herr_t   ret_value = SUCCEED;
+
+    FUNC_ENTER(H5F_get_obj_count, FAIL);
+    *obj_id_count = 0;
+
+    if(H5F_get_objects(f, types, NULL, obj_id_count) < 0)
+        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get counts of opened file IDs and object IDs in the file");
+
+done:
+    FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5Fget_object_ids
+ *
+ * Purpose:	Public function to return a list of opened object IDs.
+ *
+ * Return:	Non-negative on success; negative on failure.
+ *
+ * Programmer:  Raymond Lu
+ *              Wednesday, Dec 5, 2001
+ *
+ * Modification:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fget_obj_ids(hid_t file_id, unsigned types, hid_t *oid_list)
+{
+    herr_t   ret_value = SUCCEED;
+    H5F_t    *f=NULL;
+
+    FUNC_ENTER(H5Fget_obj_ids, FAIL);
+    H5TRACE3("e","iIu*i",file_id,types,oid_list);
+    if( file_id != H5F_OBJ_ALL && (H5I_FILE != H5I_get_type(file_id) || 
+	NULL==(f=H5I_object(file_id))) )
+        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id");
+    if( (types&H5F_OBJ_ALL)==0)
+        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type");
+    assert(oid_list);
+
+    ret_value = H5F_get_obj_ids(f, types, oid_list);
+
+done:
+    FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:    H5F_get_object_ids
+ *
+ * Purpose:     Private function to return a list of opened object IDs.
+ *
+ * Return:      Non-negative on success; negative on failure.   
+ *      
+ * Programmer:  Raymond Lu      
+ *              Wednesday, Dec 5, 2001  
+ *      
+ * Modification:        
+ *      
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_get_obj_ids(H5F_t *f, unsigned types, hid_t *oid_list)
+{
+    herr_t      ret_value = SUCCEED;
+ 
+    FUNC_ENTER(H5F_get_obj_ids, FAIL);
+
+    if(H5F_get_objects(f, types, oid_list, NULL) < 0)
+        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get object IDs opened in the file");  
+
+done:
+    FUNC_LEAVE(ret_value);
+}
+
+
+/*---------------------------------------------------------------------------
+ * Function:	H5F_get_objects
+ *
+ * Purpose:	This function is called by H5F_get_obj_count or 
+ *		H5F_get_obj_ids to get either number of object IDs or a 
+ *		list of opened object IDs.
+ * Return:	Non-negative on success; negative on failure. 
+ *
+ * Programmer:  Raymond Lu
+ *              Wednesday, Dec 5, 2001
+ *
+ * Modification:
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5F_get_objects(H5F_t *f, unsigned types, hid_t *obj_id_list, 
+		unsigned *obj_id_count)
+{
+    herr_t      ret_value = SUCCEED;
+    H5F_olist_t *olist = NULL;
+
+    FUNC_ENTER(H5F_get_object, FAIL);
+
+    olist = H5MM_malloc(sizeof(H5F_olist_t));
+    olist->obj_id_list  = obj_id_list;
+    olist->obj_id_count = obj_id_count;
+    olist->list_index   = 0;
+    /* Shared file structure is used to verify if file IDs refer to the same 
+     * file. */
+    if(f != NULL)
+        olist->shared = f->shared;
+    else
+	olist->shared = NULL;
+
+    /* Search through file IDs to count the number, and put their
+     * IDs on the object list */
+    if( (types & H5F_OBJ_FILE) && H5I_nmembers(H5I_FILE) > 0 ) {
+        olist->obj_type = H5I_FILE;
+        H5I_search(H5I_FILE, (H5I_search_func_t)H5F_get_objects_cb, olist);
+    }
+
+    /* Search through dataset IDs to count number of dataset, and put their 
+     * IDs on the object list */
+    if( (types & H5F_OBJ_DATASET) && H5I_nmembers(H5I_DATASET) > 0 ) {
+        olist->obj_type = H5I_DATASET;
+        H5I_search(H5I_DATASET, (H5I_search_func_t)H5F_get_objects_cb, olist);
+    }
+
+    /* Search through group IDs to count number of group, and put their 
+     * IDs on the object list */
+    if( (types & H5F_OBJ_GROUP) && H5I_nmembers(H5I_GROUP) > 0 ) {
+        olist->obj_type = H5I_GROUP;
+        H5I_search(H5I_GROUP, (H5I_search_func_t)H5F_get_objects_cb, olist);
+    }
+
+    /* Search through datatype IDs to count number of datatype, and put their 
+     * IDs on the object list */
+    if( (types & H5F_OBJ_DATATYPE) && H5I_nmembers(H5I_DATATYPE) > 0 ) {
+        olist->obj_type = H5I_DATATYPE;
+        H5I_search(H5I_DATATYPE, (H5I_search_func_t)H5F_get_objects_cb, olist);
+    }
+
+done:
+    if(olist!=NULL)
+	H5MM_xfree(olist);
+    FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5F_get_objects_cb 
+ *
+ * Purpose:	H5F_get_objects' callback function.  It verifies if an 
+ * 		object is in the file, and either count it or put its ID
+ *		on the list.
+ *
+ * Programmer:  Raymond Lu
+ *              Wednesday, Dec 5, 2001
+ *
+ * Modification:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
+{
+    herr_t      ret_value = SUCCEED;
+    H5F_olist_t *olist = key;
+    H5G_entry_t *ent = NULL;
+ 
+    FUNC_ENTER(H5F_get_objects_cb, FAIL);
+    assert(obj_ptr);
+    assert(olist);
+
+    /* Count file IDs */ 
+    if(olist->obj_type == H5I_FILE) {
+	if( !olist->shared || (olist->shared && ((H5F_t*)obj_ptr)->shared == 
+	    olist->shared) ) {
+            if(olist->obj_id_list) {
+                olist->obj_id_list[olist->list_index] = obj_id;
+		olist->list_index++;
+	    }
+	    if(olist->obj_id_count)
+	    	(*olist->obj_id_count)++;
+	}    
+    } else { /* either count opened object IDs or put the IDs on the list */
+    	switch(olist->obj_type) {
+	    case H5I_GROUP:
+	        ent = H5G_entof((H5G_t*)obj_ptr);
+                break;
+	    case H5I_DATASET:
+	        ent = H5D_entof((H5D_t*)obj_ptr);
+		break;
+	    case H5I_DATATYPE:
+	        ent = H5T_entof((H5T_t*)obj_ptr);
+		break;
+	}
+
+    	if( (!olist->shared && olist->obj_type==H5I_DATATYPE && 
+		H5T_is_immutable((H5T_t*)obj_ptr)==FALSE) 
+	    || (!olist->shared && olist->obj_type!=H5I_DATATYPE) 
+            || (ent && ent->file->shared == olist->shared) ) {
+            if(olist->obj_id_list) {
+            	olist->obj_id_list[olist->list_index] = obj_id;
+		olist->list_index++;
+	    }
+	    if(olist->obj_id_count)
+            	(*olist->obj_id_count)++;
+    	}
+    }
+
+done:
+    FUNC_LEAVE(ret_value); 
+}
+
 
 /*-------------------------------------------------------------------------
  * Function:	H5F_equal
@@ -854,7 +1156,7 @@ done:
  *-------------------------------------------------------------------------
  */
 static int
-H5F_equal(void *_haystack, const void *_needle)
+H5F_equal(void *_haystack, UNUSED hid_t id, const void *_needle)
 {
     H5F_t		*haystack = (H5F_t*)_haystack;
     const H5FD_t	*needle = (const H5FD_t*)_needle;
@@ -1094,7 +1396,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
 	if ((n=H5AC_create(f, f->shared->mdc_nelmts))<0)
 	    HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create meta data cache");
 	f->shared->mdc_nelmts = n;
-	
+
 	/* Create the chunk cache */
 	H5F_istore_init(f);
     } /* end else */
@@ -1319,8 +1621,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
     size_t              sizeof_size = 0;
     unsigned            sym_leaf_k = 0;
     int                 btree_k[H5B_NUM_BTREE_ID];
-    H5P_genplist_t *plist;              /* Property list */
-    
+    H5P_genplist_t      *c_plist;
+    H5P_genplist_t      *a_plist;            /* Property list */
+    H5F_close_degree_t  fc_degree;
+
     FUNC_ENTER(H5F_open, NULL);
 
     /*
@@ -1425,7 +1729,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
     file->name = H5MM_xstrdup(name);
 
     /* Get the shared file creation property list */
-    if(NULL == (plist = H5I_object(shared->fcpl_id)))
+    if(NULL == (c_plist = H5I_object(shared->fcpl_id)))
         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list");
 
     /*
@@ -1438,7 +1742,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
 	 * which we have already insured is a proper size.  The base address
 	 * is set to the same thing as the superblock for now.
 	 */
-        if(H5P_get(plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size) < 0)
+        if(H5P_get(c_plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size) < 0)
             HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get user block size");
         shared->boot_addr = userblock_size;
 	shared->base_addr = shared->boot_addr;
@@ -1465,21 +1769,21 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
         boot_vers = *p++;
         if(HDF5_BOOTBLOCK_VERSION != boot_vers) 
             HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number");
-        if(H5P_set(plist, H5F_CRT_BOOT_VERS_NAME, &boot_vers) < 0)
+        if(H5P_set(c_plist, H5F_CRT_BOOT_VERS_NAME, &boot_vers) < 0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set boot version");
 
 	/* Freespace version */
         freespace_vers = *p++;
         if(HDF5_FREESPACE_VERSION != freespace_vers) 
             HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number");
-        if(H5P_set(plist, H5F_CRT_FREESPACE_VERS_NAME, &freespace_vers)<0)
+        if(H5P_set(c_plist, H5F_CRT_FREESPACE_VERS_NAME, &freespace_vers)<0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to free space version");        
 
 	/* Root group version number */
         obj_dir_vers = *p++;
         if(HDF5_OBJECTDIR_VERSION != obj_dir_vers) 
             HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number");
-        if(H5P_set(plist, H5F_CRT_OBJ_DIR_VERS_NAME, &obj_dir_vers) < 0)
+        if(H5P_set(c_plist, H5F_CRT_OBJ_DIR_VERS_NAME, &obj_dir_vers) < 0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set object directory version");
 
 	/* reserved */
@@ -1489,7 +1793,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
         share_head_vers = *p++;
         if(HDF5_SHAREDHEADER_VERSION != share_head_vers) 
             HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number");
-        if(H5P_set(plist, H5F_CRT_SHARE_HEAD_VERS_NAME, &share_head_vers) < 0)
+        if(H5P_set(c_plist, H5F_CRT_SHARE_HEAD_VERS_NAME, &share_head_vers) < 0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set shared-header format version");
 
 	/* Size of file addresses */
@@ -1497,7 +1801,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
 	if (sizeof_addr != 2 && sizeof_addr != 4 &&
                 sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
 	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address");
-        if(H5P_set(plist, H5F_CRT_ADDR_BYTE_NUM_NAME,&sizeof_addr)<0)
+        if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME,&sizeof_addr)<0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address");
 
 	/* Size of file sizes */
@@ -1505,7 +1809,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
 	if (sizeof_size != 2 && sizeof_size != 4 &&
                 sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32)
 	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size");
-        if(H5P_set(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size)<0)
+        if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size)<0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size");
 	
 	/* Reserved byte */
@@ -1515,16 +1819,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
 	UINT16DECODE(p, sym_leaf_k);
 	if(sym_leaf_k < 1)
 	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank");
-        if(H5P_set(plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k)<0)
+        if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k)<0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes");
 
 	/* Need 'get' call to set other array values */
-        if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, btree_k)<0)
+        if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k)<0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes");        
 	UINT16DECODE(p, btree_k[H5B_SNODE_ID]);
 	if(btree_k[H5B_SNODE_ID] < 1)
 	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes");
-        if(H5P_set(plist, H5F_CRT_BTREE_RANK_NAME, btree_k)<0)
+        if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k)<0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for btree internal nodes");
 
 	/* File consistency flags. Not really used yet */
@@ -1587,7 +1891,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
 	 * The user-defined data is the area of the file before the base
 	 * address.
 	 */
-        if(H5P_set(plist, H5F_CRT_USER_BLOCK_NAME, &(shared->base_addr)) < 0)
+        if(H5P_set(c_plist, H5F_CRT_USER_BLOCK_NAME, &(shared->base_addr)) < 0)
             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set usr block size");
 
 	/*
@@ -1608,6 +1912,29 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
 	    HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to set end-of-address marker for file");
     }
 
+        /* Decide the file close degree.  If it's the first time to open the
+	 * file, set the degree to access property list value; if it's the 
+	 * second time or later, verify the access property list value matches
+	 * the degree in shared file structure.
+	 */
+        if(H5P_DEFAULT == fapl_id)
+            fapl_id = H5P_FILE_ACCESS_DEFAULT;
+        if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS) || 
+            NULL == (a_plist = H5I_object(fapl_id)))
+            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list");
+        if(H5P_get(a_plist, H5F_CLOSE_DEGREE_NAME, &fc_degree) < 0)
+            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree");  
+
+        if(shared->nrefs == 1) {
+            if(fc_degree == H5F_CLOSE_DEFAULT)
+                shared->fc_degree = H5F_CLOSE_DEFAULT;
+            else
+                shared->fc_degree = fc_degree;
+        } else if(shared->nrefs > 1) {
+            if(fc_degree != shared->fc_degree)
+                HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match");
+        }
+
     /* Success */
     ret_value = file;
 
@@ -2158,7 +2485,10 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
 herr_t
 H5F_close(H5F_t *f)
 {
-    unsigned	i;
+    unsigned		i;
+    unsigned		oid_count;
+    hid_t		*oid_list;
+    H5F_close_degree_t	fc_degree;
 
     FUNC_ENTER(H5F_close, FAIL);
     assert(f->nrefs>0);
@@ -2187,40 +2517,6 @@ H5F_close(H5F_t *f)
     }
     f->mtab.nmounts = 0;
 
-    /*
-     * If object headers are still open then delay deletion of resources until
-     * they have all been closed.  Flush all caches and update the object
-     * header anyway so that failing to close all objects isn't a major
-     * problem. If the file is on the H5I_FILE list then move it to the
-     * H5I_FILE_CLOSING list instead.
-     */
-    if (f->nopen_objs>0) {
-	if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE)<0) {
-	    HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
-			  "unable to flush cache");
-	}
-#ifdef H5F_DEBUG
-	if (H5DEBUG(F)) {
-	    fprintf(H5DEBUG(F), "H5F: H5F_close(%s): %u object header%s still "
-		    "open (file close will complete when %s closed)\n",
-		    f->name,
-		    f->nopen_objs,
-		    1 == f->nopen_objs?" is":"s are",
-		    1 == f->nopen_objs?"that header is":"those headers are");
-	}
-#endif
-	if (!f->closing) {
-	    f->closing  = H5I_register(H5I_FILE_CLOSING, f);
-	}
-	HRETURN(SUCCEED);
-    } else if (f->closing) {
-#ifdef H5F_DEBUG
-	if (H5DEBUG(F)) {
-	    fprintf(H5DEBUG(F), "H5F: H5F_close: operation completing\n");
-	}
-#endif
-    }
-
     /*
      * If this is the last reference to the shared part of the file then
      * close it also.
@@ -2233,6 +2529,95 @@ H5F_close(H5F_t *f)
 			  "unable to flush cache");
 	}
 
+	/* Get the number of opened object in file */
+        if(H5F_get_obj_count(f, H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE,
+	    &oid_count) < 0)
+            HRETURN_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file counts");
+
+	/* Get the close degree from the file */
+        if(f->shared->fc_degree == H5F_CLOSE_DEFAULT)
+	    fc_degree = f->shared->lf->cls->fc_degree;
+	else
+	    fc_degree = f->shared->fc_degree;
+
+	/* Close file according to close degree.
+	 * H5F_CLOSE_WEAK:	if there are still objects open, wait until
+	 *			they are all closed.
+	 * H5F_CLOSE_SEMI:	if there are still objects open, return fail;
+	 *			otherwise, close file.
+	 * H5F_CLOSE_STRONG:	if there are still objects open, close them
+	 *			first, then close file. 
+	 */ 
+        switch(fc_degree) {
+	    case H5F_CLOSE_WEAK:
+	   	/*
+		 * If object headers are still open then delay deletion of 
+		 * resources until they have all been closed.  Flush all 
+		 * caches and update the object eader anyway so that failing toi
+		 * close all objects isn't a major problem. If the file is on 
+		 * the H5I_FILE list then move it to the H5I_FILE_CLOSING list 
+		 * instead.
+		 */ 
+		if (f->nopen_objs>0) {
+		    if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE)<0) 
+            		HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
+                        		"unable to flush cache");
+#ifdef H5F_DEBUG
+        	    if (H5DEBUG(F)) {
+            	    	fprintf(H5DEBUG(F), "H5F: H5F_close(%s): %u object header%s still "
+                    	"open (file close will complete when %s closed)\n",
+                    	f->name,
+                    	f->nopen_objs,
+                    	1 == f->nopen_objs?" is":"s are",
+                    	1 == f->nopen_objs?"that header is":"those headers are");
+        	    }
+#endif
+	            if (!f->closing) {
+            		f->closing  = H5I_register(H5I_FILE_CLOSING, f);
+        	    }
+        	    HRETURN(SUCCEED);
+    		} else if (f->closing) {
+#ifdef H5F_DEBUG
+        	    if (H5DEBUG(F)) {
+            	        fprintf(H5DEBUG(F), "H5F: H5F_close: operation completing\n");
+        	    }
+#endif
+    		}
+
+		break;
+	    case H5F_CLOSE_SEMI:
+		if(oid_count > 0)
+                    HRETURN_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, 
+                    "can't close file, there are objects still open");
+		break;
+	    case H5F_CLOSE_STRONG:
+		/*forcefully close all opened objects in file*/
+		do {
+		    oid_list = (hid_t*)H5MM_malloc(oid_count*sizeof(hid_t));
+		    if(H5F_get_obj_ids(f, H5F_OBJ_DATASET|H5F_OBJ_GROUP|
+					H5F_OBJ_DATATYPE, oid_list) < 0)
+            		HRETURN_ERROR(H5E_FILE, H5E_CANTGET, FAIL, 
+                                      "can't get object list in file");
+                   
+		    /* Try to close all the open objects */
+                    for(i=0; i<oid_count; i++)
+		    	if(H5I_dec_ref(oid_list[i]) < 0)
+			    HRETURN_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL,
+                            			"can't close object");
+
+		    if(oid_list != NULL)
+			H5MM_xfree(oid_list);
+		    if(H5F_get_obj_count(f, H5F_OBJ_DATASET|H5F_OBJ_GROUP|
+					H5F_OBJ_DATATYPE, &oid_count) < 0)
+		    	HRETURN_ERROR(H5E_FILE, H5E_CANTGET, FAIL, 
+		    			"can't get file counts");
+		} while(oid_count > 0);
+		break;
+	    default:
+		HRETURN_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL,
+                    "can't close file, unknown file close degree"); 	
+	}
+
 	/* Dump debugging info */
 	H5AC_debug(f);
 	H5F_istore_stats(f, FALSE);
@@ -2284,19 +2669,15 @@ H5F_close(H5F_t *f)
 herr_t
 H5Fclose(hid_t file_id)
 {
-    
     herr_t	ret_value = SUCCEED;
-
+ 
     FUNC_ENTER(H5Fclose, FAIL);
     H5TRACE1("e","i",file_id);
 
     /* Check/fix arguments. */
-    if (H5I_FILE != H5I_get_type(file_id)) {
+    if (H5I_FILE != H5I_get_type(file_id) || NULL==H5I_object(file_id)) {
 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file atom");
     }
-    if (NULL == H5I_object(file_id)) {
-	HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to unatomize file");
-    }
 
     /*
      * Decrement reference count on atom.  When it reaches zero the file will
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 206f5e6976..13a4a01f3d 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -92,6 +92,7 @@ static herr_t H5FD_core_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, had
 static const H5FD_class_t H5FD_core_g = {
     "core",					/*name			*/
     MAXADDR,					/*maxaddr		*/
+    H5F_CLOSE_WEAK,				/*fc_degree		*/
     NULL,					/*sb_size		*/
     NULL,					/*sb_encode		*/
     NULL,					/*sb_decode		*/
diff --git a/src/H5FDdpss.c b/src/H5FDdpss.c
index 87f86f5ccf..9884c3b64a 100644
--- a/src/H5FDdpss.c
+++ b/src/H5FDdpss.c
@@ -140,6 +140,7 @@ static herr_t H5FD_dpss_write (H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED fapl
 static const H5FD_class_t H5FD_dpss_g = {
     "dpss",                                        /* name           */
     MAXADDR,                                       /* maxaddr        */
+    H5F_CLOSE_WEAK,				   /* fc_degree	     */
     NULL,                                          /* sb_size        */
     NULL,                                          /* sb_encode      */
     NULL,                                          /* sb_decode      */
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index 80feac2754..16c2265df1 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -87,6 +87,7 @@ static herr_t H5FD_family_flush(H5FD_t *_file);
 static const H5FD_class_t H5FD_family_g = {
     "family",					/*name			*/
     HADDR_MAX,					/*maxaddr		*/
+    H5F_CLOSE_WEAK,				/* fc_degree		*/
     NULL,					/*sb_size		*/
     NULL,					/*sb_encode		*/
     NULL,					/*sb_decode		*/
diff --git a/src/H5FDgass.c b/src/H5FDgass.c
index 25bcdaf4fc..12040cdd20 100644
--- a/src/H5FDgass.c
+++ b/src/H5FDgass.c
@@ -133,6 +133,7 @@ typedef struct H5FD_gass_fapl_t {
 static const H5FD_class_t H5FD_gass_g = {
     "gass",					/*name			*/
     MAXADDR,					/*maxaddr		*/
+    H5F_CLOSE_WEAK,				/* fc_degree		*/
     NULL,					/*sb_size		*/
     NULL,					/*sb_encode		*/
     NULL,					/*sb_decode		*/
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index 11162b60df..b1a9848156 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -193,6 +193,7 @@ static herr_t H5FD_log_flush(H5FD_t *_file);
 static const H5FD_class_t H5FD_log_g = {
     "log",					/*name			*/
     MAXADDR,					/*maxaddr		*/
+    H5F_CLOSE_WEAK,				/* fc_degree		*/
     NULL,					/*sb_size		*/
     NULL,					/*sb_encode		*/
     NULL,					/*sb_decode		*/
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index 9209050147..437d18f64c 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -93,6 +93,7 @@ typedef struct H5FD_mpio_fapl_t {
 static const H5FD_class_t H5FD_mpio_g = {
     "mpio",					/*name			*/
     HADDR_MAX,					/*maxaddr		*/
+    H5F_CLOSE_SEMI,				/* fc_degree		*/
     NULL,					/*sb_size		*/
     NULL,					/*sb_encode		*/
     NULL,					/*sb_decode		*/
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index d7d67b1319..b554b888da 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -133,6 +133,7 @@ static herr_t H5FD_multi_flush(H5FD_t *_file);
 static const H5FD_class_t H5FD_multi_g = {
     "multi",					/*name			*/
     HADDR_MAX,					/*maxaddr		*/
+    H5F_CLOSE_WEAK,				/* fc_degree		*/
     H5FD_multi_sb_size,				/*sb_size		*/
     H5FD_multi_sb_encode,			/*sb_encode		*/
     H5FD_multi_sb_decode,			/*sb_decode		*/
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index 66358bef86..d2883074ca 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -9,6 +9,7 @@
 #define _H5FDpublic_H
 
 #include "H5public.h"
+#include "H5Fpublic.h"		/*for H5F_close_degree_t */
 
 #define H5_HAVE_VFL 1 /*define a convenient app feature test*/
 #define H5FD_VFD_DEFAULT 0   /* Default VFL driver value */
@@ -108,6 +109,7 @@ typedef struct H5FD_t H5FD_t;
 typedef struct H5FD_class_t {
     const char *name;
     haddr_t maxaddr;
+    H5F_close_degree_t fc_degree;
     hsize_t (*sb_size)(H5FD_t *file);
     herr_t (*sb_encode)(H5FD_t *file, char *name/*out*/,
 			unsigned char *p/*out*/);
@@ -149,28 +151,28 @@ typedef struct H5FD_free_t {
  * declared here and the driver appends private fields in memory.
  */
 struct H5FD_t {
-    hid_t		driver_id;	/*driver ID for this file	*/
-    const H5FD_class_t	*cls;		/*constant class info		*/
+    hid_t			driver_id;	/*driver ID for this file*/
+    const H5FD_class_t		*cls;		/*constant class info	*/
 
-    unsigned long feature_flags;  /* VFL Driver feature Flags */
-    hsize_t     threshold;      /* Threshold for alignment              */
-    hsize_t     alignment;      /* Allocation alignment                 */
+    unsigned long 		feature_flags;  /* VFL Driver feature Flags */
+    hsize_t     		threshold;      /* Threshold for alignment  */
+    hsize_t     		alignment;      /* Allocation alignment     */
 
     /* Metadata aggregation fields */
-    hsize_t def_meta_block_size;  /* Metadata allocation block size (if aggregating metadata) */
-    hsize_t cur_meta_block_size;  /* Current size of metadata allocation region left */
-    haddr_t eoma;       /* End of metadata allocated region */
+    hsize_t 			def_meta_block_size;  /* Metadata allocation block size (if aggregating metadata) */
+    hsize_t 			cur_meta_block_size;  /* Current size of metadata allocation region left */
+    haddr_t 			eoma;       /*End of metadata allocated region*/
 
     /* Metadata accumulator fields */
-    unsigned char *meta_accum;  /* Buffer to hold the accumulated metadata */
-    haddr_t accum_loc;      /* File location (offset) of the accumulated metadata */
-    size_t accum_size;      /* Size of the accumulated metadata buffer used (in bytes) */
-    size_t accum_buf_size;  /* Size of the accumulated metadata buffer allocated (in bytes) */
-    unsigned accum_dirty;   /* Flag to indicate that the accumulated metadata is dirty */
+    unsigned char 		*meta_accum; /*Buffer to hold the accumulated metadata */
+    haddr_t 			accum_loc;      /* File location (offset) of the accumulated metadata */
+    size_t 			accum_size;      /* Size of the accumulated metadata buffer used (in bytes) */
+    size_t 			accum_buf_size;  /* Size of the accumulated metadata buffer allocated (in bytes) */
+    unsigned 			accum_dirty;   /* Flag to indicate that the accumulated metadata is dirty */
 
-    haddr_t		maxaddr;	/*for this file, overrides class*/
-    H5FD_free_t		*fl[H5FD_MEM_NTYPES];/*freelist per allocation type*/
-    hsize_t		maxsize;	/*largest object on FL, or zero	*/
+    haddr_t			maxaddr;/*for this file, overrides class*/
+    H5FD_free_t			*fl[H5FD_MEM_NTYPES];/*freelist per allocation type*/
+    hsize_t			maxsize;/*largest object on FL, or zero	*/
 };
 
 #ifdef __cplusplus
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index 04bcb16b46..df150a720c 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -149,6 +149,7 @@ static herr_t H5FD_sec2_flush(H5FD_t *_file);
 static const H5FD_class_t H5FD_sec2_g = {
     "sec2",					/*name			*/
     MAXADDR,					/*maxaddr		*/
+    H5F_CLOSE_WEAK,				/* fc_degree		*/
     NULL,					/*sb_size		*/
     NULL,					/*sb_encode		*/
     NULL,					/*sb_decode		*/
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index d86dbac2e5..d292727fa1 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -144,6 +144,7 @@ static herr_t H5FD_stdio_flush(H5FD_t *_file);
 static const H5FD_class_t H5FD_stdio_g = {
     "stdio",				        /*name			*/
     MAXADDR,				        /*maxaddr		*/
+    H5F_CLOSE_WEAK,				/* fc_degree		*/
     NULL,					/*sb_size		*/
     NULL,					/*sb_encode		*/
     NULL,					/*sb_decode		*/
diff --git a/src/H5FDstream.c b/src/H5FDstream.c
index 7572e45c5c..581c0b74e7 100644
--- a/src/H5FDstream.c
+++ b/src/H5FDstream.c
@@ -171,6 +171,7 @@ static const H5FD_class_t H5FD_stream_g =
 {
   "stream",                         /* name                                */
   MAXADDR,                          /* maxaddr                             */
+  H5F_CLOSE_WEAK,		    /* fc_degree			   */
   NULL,                             /* sb_size                             */
   NULL,                             /* sb_encode                           */
   NULL,                             /* sb_decode                           */
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 0bff2a8c46..822896dd07 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -119,6 +119,7 @@ typedef struct H5F_file_t {
     unsigned sieve_dirty;       /* Flag to indicate that the data sieve buffer is dirty */
 
     H5F_rdcc_t	rdcc;		/* Raw data chunk cache			*/
+    H5F_close_degree_t fc_degree;	/* File close behavior degree	*/
 } H5F_file_t;
 
 /* A record of the mount table */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index cedfc3851e..ed5daf60ba 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -306,6 +306,11 @@ __DLL__ size_t H5F_sizeof_size(const H5F_t *f);
 #define H5F_ACS_FILE_DRV_INFO_SIZE             sizeof(void*)
 #define H5F_ACS_FILE_DRV_INFO_DEF              NULL
 
+/* Definition for file close degree */
+#define H5F_CLOSE_DEGREE_NAME		       "close_degree"
+#define H5F_CLOSE_DEGREE_SIZE		       sizeof(H5F_close_degree_t)
+#define H5F_CLOSE_DEGREE_DEF		       H5F_CLOSE_DEFAULT
+
 /* ======================== File Mount properties ====================*/
 /* Definition for whether absolute symlinks local to file. */
 #define H5F_MNT_SYM_LOCAL_NAME 		"local"
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 5309b022e0..b7db6de1ac 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -36,6 +36,11 @@
 #define H5F_ACC_DEBUG	(H5check(),0x0008u)	/*print debug info	     */
 #define H5F_ACC_CREAT	(H5check(),0x0010u)	/*create non-existing files  */
 
+#define H5F_OBJ_FILE	(0x0001u)
+#define H5F_OBJ_DATASET	(0x0002u)
+#define H5F_OBJ_GROUP	(0x0004u)
+#define H5F_OBJ_DATATYPE (0x0008u)
+#define H5F_OBJ_ALL 	(H5F_OBJ_FILE|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE)
 
 #ifdef H5_HAVE_PARALLEL
 /*
@@ -64,21 +69,39 @@ typedef enum H5T_bkg_t {
     H5T_BKG_YES		= 2	/*init bkg buf with data before conversion   */
 } H5T_bkg_t;
 
+/* How does file close behave?
+ * H5F_CLOSE_DEFAULT - Use the degree pre-defined by underlining VFL
+ * H5F_CLOSE_WEAK    - file closes only after all opened objects are closed 
+ * H5F_CLOSE_SEMI    - if no opened objects, file is close; otherwise, file
+		       close fails
+ * H5F_CLOSE_STRONG  - if there are opened objects, close them first, then
+		       close file
+ */
+typedef enum H5F_close_degree_t {
+    H5F_CLOSE_DEFAULT   = 0,
+    H5F_CLOSE_WEAK      = 1,
+    H5F_CLOSE_SEMI      = 2,
+    H5F_CLOSE_STRONG    = 3
+} H5F_close_degree_t;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* Functions in H5F.c */
 __DLL__ htri_t H5Fis_hdf5 (const char *filename);
-__DLL__ hid_t H5Fcreate (const char *filename, unsigned flags,
-			 hid_t create_plist, hid_t access_plist);
-__DLL__ hid_t H5Fopen (const char *filename, unsigned flags,
-		       hid_t access_plist);
-__DLL__ hid_t H5Freopen(hid_t file_id);
+__DLL__ hid_t  H5Fcreate (const char *filename, unsigned flags,
+		  	  hid_t create_plist, hid_t access_plist);
+__DLL__ hid_t  H5Fopen (const char *filename, unsigned flags,
+		        hid_t access_plist);
+__DLL__ hid_t  H5Freopen(hid_t file_id);
 __DLL__ herr_t H5Fflush(hid_t object_id, H5F_scope_t scope);
 __DLL__ herr_t H5Fclose (hid_t file_id);
-__DLL__ hid_t H5Fget_create_plist (hid_t file_id);
-__DLL__ hid_t H5Fget_access_plist (hid_t file_id);
+__DLL__ hid_t  H5Fget_create_plist (hid_t file_id);
+__DLL__ hid_t  H5Fget_access_plist (hid_t file_id);
+__DLL__ herr_t H5Fget_obj_count(hid_t file_id, unsigned types, 
+                                unsigned *obj_id_count);
+__DLL__ herr_t H5Fget_obj_ids(hid_t file_id, unsigned types, hid_t *obj_id_list);
 __DLL__ herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist);
 __DLL__ herr_t H5Funmount(hid_t loc, const char *name);
 
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 2bc158c860..75905977b5 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -93,6 +93,7 @@ typedef struct H5G_entry_t {
     H5G_cache_t cache;                  /*cached data from object header     */
     H5F_t       *file;                  /*file to which this obj hdr belongs */
 } H5G_entry_t;
+
 typedef struct H5G_t H5G_t;
 
 /*
diff --git a/src/H5I.c b/src/H5I.c
index 6f58e09abe..65815a4733 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -888,6 +888,11 @@ H5I_remove(hid_t id)
  *	removed from the group and its reference count is not decremented.
  *	The group number is now passed to the free method.
  *
+ *	Raymond, 11 Dec 2001
+ *	If the freeing function fails, return failure instead of reference
+ *	count 1.  This feature is needed by file close with H5F_CLOSE_SEMI
+ *	value.
+ *
  *-------------------------------------------------------------------------
  */
 int
@@ -924,7 +929,7 @@ H5I_dec_ref(hid_t id)
 		H5I_remove(id);
 		ret_value = 0;
 	    } else {
-		ret_value = 1;
+		ret_value = FAIL;
 	    }
 	} else {
 	    ret_value = --(id_ptr->count);
@@ -1020,7 +1025,7 @@ H5I_search(H5I_type_t grp, H5I_search_func_t func, const void *key)
     for (i=0; i<grp_ptr->hash_size; i++) {
 	id_ptr = grp_ptr->id_list[i];
 	while (id_ptr) {
-	    if ((*func)(id_ptr->obj_ptr, key)) {
+	    if ((*func)(id_ptr->obj_ptr, id_ptr->id, key)) {
 		HGOTO_DONE(id_ptr->obj_ptr);	/*found the item*/
 	    }
 	    id_ptr = id_ptr->next;
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index abf2a4ed7a..bb289a081d 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -50,7 +50,7 @@
 typedef herr_t (*H5I_free_t)(void*);
 
 /* Type of the function to compare objects & keys */
-typedef int (*H5I_search_func_t)(void *obj, const void *key);
+typedef int (*H5I_search_func_t)(void *obj, hid_t id, const void *key);
 
 /* Atom information structure used */
 typedef struct H5I_id_info_t {
diff --git a/src/H5P.c b/src/H5P.c
index f1f6a5ccf8..952c9a9e67 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -3471,13 +3471,91 @@ H5Pget_gc_references(hid_t plist_id, unsigned *gc_ref/*out*/)
 
     /* Get values */
     if (gc_ref)
+
         if(H5P_get(plist, H5F_ACS_GARBG_COLCT_REF_NAME, gc_ref) < 0)
+
             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get garbage collect reference");
 
 done:
     FUNC_LEAVE(ret_value);
 }
 
+
+/*-------------------------------------------------------------------------
+ * Function:    H5Pset_fclose_degree
+ *
+ * Purpose:     Sets the degree for the file close behavior.
+ *
+ * Return:      Non-negative on success/Negative on failure
+ *
+ * Programmer:  Raymond Lu 
+ *              November, 2001 
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_fclose_degree(hid_t plist_id, H5F_close_degree_t degree)
+{
+    H5P_genplist_t *plist;      /* Property list pointer */
+    herr_t ret_value=SUCCEED;   /* return value */
+
+    FUNC_ENTER(H5Pset_fclose_degree, FAIL);
+
+    /* Check args */
+    if(TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS))
+        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");   
+
+    /* Get the plist structure */
+    if(NULL == (plist = H5I_object(plist_id)))
+        HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+    /* Set values */
+    if(H5P_set(plist, H5F_CLOSE_DEGREE_NAME, &degree) < 0)
+        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree");
+
+done:
+    FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function:    H5Pget_fclose_degree
+ *
+ * Purpose:     Returns the current setting for the garbage collection
+ *
+ * Return:      Non-negative on success/Negative on failure
+ *
+ * Programmer:  Quincey Koziol
+ *              June, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5Pget_fclose_degree(hid_t plist_id, H5F_close_degree_t *degree)
+{
+    H5P_genplist_t *plist;      /* Property list pointer */
+    herr_t ret_value=SUCCEED;   /* return value */
+
+    FUNC_ENTER(H5Pget_fclose_degree, FAIL);
+
+    /* Check args */
+    if(TRUE != H5P_isa_class(plist_id, H5P_FILE_ACCESS))
+        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");  
+
+    /* Get the plist structure */
+    if(NULL == (plist = H5I_object(plist_id)))
+        HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+
+    if( degree && (H5P_get(plist, H5F_CLOSE_DEGREE_NAME, degree) < 0) ) 
+        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file close degree");
+
+done:
+    FUNC_LEAVE(ret_value);
+} 
+
 
 /*-------------------------------------------------------------------------
  * Function:	H5P_set_vlen_mem_manager
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 5f404b6dad..1f5bc65dba 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -232,6 +232,8 @@ __DLL__ herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id,
      void *value/*out*/);
 __DLL__ herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref);
 __DLL__ herr_t H5Pget_gc_references(hid_t fapl_id, unsigned *gc_ref/*out*/);
+__DLL__ herr_t H5Pset_fclose_degree(hid_t fapl_id, H5F_close_degree_t degree);
+__DLL__ herr_t H5Pget_fclose_degree(hid_t fapl_id, H5F_close_degree_t *degree);
 __DLL__ herr_t H5Pset_vlen_mem_manager(hid_t plist_id,
                                        H5MM_allocate_t alloc_func,
                                        void *alloc_info, H5MM_free_t free_func,
diff --git a/src/H5T.c b/src/H5T.c
index 299f98ca5b..f0d11eb973 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -1924,7 +1924,7 @@ done:
  *-------------------------------------------------------------------------
  */
 static int
-H5T_unlock_cb (void *_dt, const void * UNUSED key)
+H5T_unlock_cb (void *_dt, hid_t id,  const void * UNUSED key)
 {
     H5T_t	*dt = (H5T_t *)_dt;
     
@@ -7639,6 +7639,37 @@ H5T_entof (H5T_t *dt)
     FUNC_LEAVE (ret_value);
 }
 
+
+/*-------------------------------------------------------------------------
+ * Function:    H5T_is_immutable
+ *
+ * Purpose:     Check is a datatype is immutable. 
+ *
+ * Return:      TRUE 
+ *
+ *              FALSE 
+ *
+ * Programmer:  Raymond Lu 
+ *              Friday, Dec 7, 2001 
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5T_is_immutable(H5T_t *dt)
+{
+    htri_t ret_value = FALSE;
+
+    FUNC_ENTER(H5T_is_immutable, FAIL);
+    assert(dt);
+
+    if(dt->state == H5T_STATE_IMMUTABLE)
+	ret_value = TRUE;
+
+    FUNC_LEAVE(ret_value);
+}
+
 
 /*--------------------------------------------------------------------------
  NAME
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 7082b50c23..f815705989 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -131,7 +131,7 @@ struct H5T_t {
     H5F_t		*sh_file;/*file pointer if this is a shared type     */
     H5T_class_t		type;	/*which class of type is this?		     */
     size_t		size;	/*total size of an instance of this type     */
-    hbool_t     force_conv; /* Set if this type always needs to be converted and H5T_conv_noop cannot be called */
+    hbool_t     force_conv;     /* Set if this type always needs to be converted and H5T_conv_noop cannot be called */
     struct H5T_t	*parent;/*parent type for derived data types	     */
     union {
         H5T_atomic_t	atomic; /* an atomic data type              */
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 72f068ac55..23cd9a3e01 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -116,6 +116,7 @@ __DLL__ herr_t H5T_enum_insert(H5T_t *dt, const char *name, void *value);
 __DLL__ herr_t H5T_pack(H5T_t *dt);
 __DLL__ herr_t H5T_debug(const H5T_t *dt, FILE * stream);
 __DLL__ H5G_entry_t *H5T_entof(H5T_t *dt);
+__DLL__ htri_t H5T_is_immutable(H5T_t *dt);
 __DLL__ H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst,
 				  const char *name, H5T_conv_t func);
 __DLL__ herr_t H5T_sort_value(H5T_t *dt, int *map);
diff --git a/test/dsets.c b/test/dsets.c
index 80ca27d51e..739af4a25e 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -754,6 +754,7 @@ test_types(hid_t file)
     for (i=0; i<sizeof buf; i++) buf[i] = (unsigned char)0xff ^ (unsigned char)i;
     if (H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf)<0)
 	goto error;
+
     if (H5Sclose(space)<0) goto error;
     if (H5Tclose(type)<0) goto error;
     if (H5Dclose(dset)<0) goto error;
diff --git a/test/tfile.c b/test/tfile.c
index 308188a041..98da5e71ae 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -50,6 +50,19 @@
 #define F3_SYM_INTERN_K	   F2_SYM_INTERN_K
 #define FILE3	"tfile3.h5"
 
+#define OBJ_ID_COUNT_0     0
+#define OBJ_ID_COUNT_1     1 
+#define OBJ_ID_COUNT_2     2
+#define OBJ_ID_COUNT_3     3 
+#define OBJ_ID_COUNT_4     4 
+#define OBJ_ID_COUNT_6	   6    
+#define OBJ_ID_COUNT_8     8 
+
+static void
+create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *);
+static void
+test_obj_count_and_id(hid_t, hid_t, hid_t, hid_t, hid_t, hid_t);
+
 /****************************************************************
 **
 **  test_file_create(): Low-level file creation I/O test routine.
@@ -343,6 +356,483 @@ test_file_open(void)
     CHECK(ret, FAIL, "H5Fclose");
 }				/* test_file_open() */
 
+/****************************************************************
+**
+**  test_file_close():  low-level file close test routine.  
+**                      It mainly tests behavior with close degree.
+**
+*****************************************************************/
+static void 
+test_file_close()
+{
+    hid_t               fid1, fid2;
+    hid_t               fapl_id, access_id;
+    hid_t		dataset_id, group_id1, group_id2, group_id3;
+    H5F_close_degree_t  fc_degree;
+    unsigned            fid_count, oid_count;
+    herr_t              ret;
+
+    /* Test behavior while opening file multiple times with different
+     * file close degree value
+     */
+    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    CHECK(fid1, FAIL, "H5Fcreate");
+ 
+    fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+    CHECK(fapl_id, FAIL, "H5Pcreate");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    ret = H5Pget_fclose_degree(fapl_id, &fc_degree);
+    VERIFY(fc_degree, H5F_CLOSE_STRONG, "H5Pget_fclose_degree");
+
+    /* should fail */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    VERIFY(fid2, FAIL, "H5Fopen");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+   
+    /* should succeed */ 
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    CHECK(fid2, FAIL, "H5Fopen");
+
+    /* Close first open */
+    ret = H5Fclose(fid1);
+    CHECK(ret, FAIL, "H5Fclose");
+
+    /* Close second open */
+    ret = H5Fclose(fid2);
+    CHECK(ret, FAIL, "H5Fclose");
+
+
+    /* Test behavior while opening file multiple times with file close 
+     * degree STRONG */
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
+    CHECK(fid1, FAIL, "H5Fcreate");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should fail */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    VERIFY(fid2, FAIL, "H5Fopen");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should succeed */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    CHECK(fid2, FAIL, "H5Fopen");
+
+    /* Create a dataset and a group in each file open respectively */
+    create_objects(fid1, fid2, NULL, NULL, NULL, NULL);
+
+    /* Close first open */
+    ret = H5Fclose(fid1);
+    CHECK(ret, FAIL, "H5Fclose");
+
+    /* Close second open */
+    ret = H5Fclose(fid2);
+    CHECK(ret, FAIL, "H5Fclose");
+
+
+    /* Test behavior while opening file multiple times with file close
+     * degree SEMI */
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
+    CHECK(fid1, FAIL, "H5Fcreate");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should fail */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    VERIFY(fid2, FAIL, "H5Fopen");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should succeed */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    CHECK(fid2, FAIL, "H5Fopen");
+
+    /* Create a dataset and a group in each file open respectively */
+    create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3);
+
+    /* Close first open */
+    ret = H5Fclose(fid1);
+    CHECK(ret, FAIL, "H5Fclose");
+
+    /* Close second open, should fail since it is SEMI and objects are 
+     * still open. */
+    ret = H5Fclose(fid2);
+    VERIFY(ret, FAIL, "H5Fclose");
+
+    ret = H5Dclose(dataset_id);
+    CHECK(ret, FAIL, "H5Dclose");
+  
+    ret = H5Gclose(group_id1);
+    CHECK(ret, FAIL, "H5Gclose");
+
+    ret = H5Gclose(group_id2);
+    CHECK(ret, FAIL, "H5Gclose");
+
+    /* Close second open, should fail since it is SEMI and one group ID is 
+     * still open. */
+    ret = H5Fclose(fid2);
+    VERIFY(ret, FAIL, "H5Fclose");
+
+    ret = H5Gclose(group_id3);
+    CHECK(ret, FAIL, "H5Gclose");
+
+    /* Close second open again.  Should succeed. */
+    ret = H5Fclose(fid2);
+    CHECK(ret, FAIL, "H5Fclose");
+
+
+    /* Test behavior while opening file multiple times with file close
+     * degree WEAK */
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
+    CHECK(fid1, FAIL, "H5Fcreate");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should fail */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    VERIFY(fid2, FAIL, "H5Fopen");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should succeed */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    CHECK(fid2, FAIL, "H5Fopen");
+
+    /* Create a dataset and a group in each file open respectively */
+    create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3);
+
+    /* Create more new files and test object count and ID list functions */
+    test_obj_count_and_id(fid1, fid2, dataset_id, group_id1, 
+				group_id2, group_id3);
+ 
+    /* Close first open */
+    ret = H5Fclose(fid1);
+    CHECK(ret, FAIL, "H5Fclose");
+
+    /* Close second open.  File will be finally closed after all objects 
+     * are closed. */
+    ret = H5Fclose(fid2);
+    CHECK(ret, FAIL, "H5Fclose");
+
+    ret = H5Dclose(dataset_id);
+    CHECK(ret, FAIL, "H5Dclose");
+
+    ret = H5Gclose(group_id1);
+    CHECK(ret, FAIL, "H5Gclose");
+
+    ret = H5Gclose(group_id2);
+    CHECK(ret, FAIL, "H5Gclose");
+
+    ret = H5Gclose(group_id3);
+    CHECK(ret, FAIL, "H5Gclose");
+
+
+    /* Test behavior while opening file multiple times with file close
+     * degree DEFAULT */
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
+    CHECK(fid1, FAIL, "H5Fcreate");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should fail */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    VERIFY(fid2, FAIL, "H5Fopen");
+
+    ret = H5Pset_fclose_degree(fapl_id, H5F_CLOSE_DEFAULT);
+    CHECK(ret, FAIL, "H5Pset_fclose_degree");
+
+    /* should succeed */
+    fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, fapl_id);
+    CHECK(fid2, FAIL, "H5Fopen");
+
+    /* Create a dataset and a group in each file open respectively */
+    create_objects(fid1, fid2, &dataset_id, &group_id1, &group_id2, &group_id3);
+    
+    access_id = H5Fget_access_plist(fid1);
+    CHECK(access_id, FAIL, "H5Fget_access_plist");
+
+    ret= H5Pget_fclose_degree(access_id, &fc_degree);
+    CHECK(ret, FAIL, "H5Pget_fclose_degree");
+
+    switch(fc_degree) {
+	case H5F_CLOSE_STRONG:
+    	    /* Close first open */
+    	    ret = H5Fclose(fid1);
+    	    CHECK(ret, FAIL, "H5Fclose");
+    	    /* Close second open */
+    	    ret = H5Fclose(fid2);
+    	    CHECK(ret, FAIL, "H5Fclose");
+	    break;
+	case H5F_CLOSE_SEMI:
+            /* Close first open */
+            ret = H5Fclose(fid1);
+            CHECK(ret, FAIL, "H5Fclose");
+    	    ret = H5Dclose(dataset_id);
+            CHECK(ret, FAIL, "H5Dclose");
+            ret = H5Gclose(group_id1);
+    	    CHECK(ret, FAIL, "H5Gclose");
+            ret = H5Gclose(group_id2);
+            CHECK(ret, FAIL, "H5Gclose");
+            ret = H5Gclose(group_id3);
+            CHECK(ret, FAIL, "H5Gclose");
+            /* Close second open */
+            ret = H5Fclose(fid2);
+            CHECK(ret, FAIL, "H5Fclose");
+	    break;
+	case H5F_CLOSE_WEAK:
+            /* Close first open */
+            ret = H5Fclose(fid1);
+            CHECK(ret, FAIL, "H5Fclose");
+            /* Close second open */
+            ret = H5Fclose(fid2);
+            CHECK(ret, FAIL, "H5Fclose");
+            ret = H5Dclose(dataset_id);
+            CHECK(ret, FAIL, "H5Dclose");
+            ret = H5Gclose(group_id1);
+            CHECK(ret, FAIL, "H5Gclose");
+            ret = H5Gclose(group_id2);
+            CHECK(ret, FAIL, "H5Gclose");
+            ret = H5Gclose(group_id3);
+            CHECK(ret, FAIL, "H5Gclose");
+	    break;
+    }
+
+    /* Close file access property list */
+    ret = H5Pclose(fapl_id);
+    CHECK(ret, FAIL, "H5Pclose");
+    ret = H5Pclose(access_id);
+    CHECK(ret, FAIL, "H5Pclose");
+}
+
+/****************************************************************
+**
+**  create_objects(): routine called by test_file_close to create
+**                    a dataset and a group in file.
+**
+****************************************************************/
+static void
+create_objects(hid_t fid1, hid_t fid2, hid_t *ret_did, hid_t *ret_gid1, 
+		hid_t *ret_gid2, hid_t *ret_gid3)
+{
+    unsigned	oid_count;
+    herr_t	ret;
+
+    /* Check reference counts of file IDs and opened object IDs.
+     * The verification is hard-coded.  If in any case, this testing
+     * is changed, remember to check this part and update the macros.
+     */
+    {
+       ret = H5Fget_obj_count(fid1, H5F_OBJ_ALL, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_2, "H5Fget_obj_count");
+
+       ret = H5Fget_obj_count(fid1, H5F_OBJ_DATASET|H5F_OBJ_GROUP|
+				H5F_OBJ_DATATYPE, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count");
+
+       ret = H5Fget_obj_count(fid2, H5F_OBJ_ALL, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_2, "H5Fget_obj_count");
+
+       ret = H5Fget_obj_count(fid2, H5F_OBJ_DATASET|H5F_OBJ_GROUP|
+                                H5F_OBJ_DATATYPE, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count");
+    }
+
+    /* create a dataset in the first file open */
+    {
+       hid_t       dataset_id, dataspace_id;  /* identifiers */
+       hsize_t     dims[F2_RANK];
+       int         data[F2_DIM0][F2_DIM1];
+       unsigned    i,j;
+
+       /* Create the data space for the dataset. */
+       dims[0] = F2_DIM0;
+       dims[1] = F2_DIM1;
+       dataspace_id = H5Screate_simple(F2_RANK, dims, NULL);
+       CHECK(dataspace_id, FAIL, "H5Screate_simple");
+
+       /* Create the dataset. */
+       dataset_id = H5Dcreate(fid1, "/dset", H5T_NATIVE_INT, dataspace_id,
+                        H5P_DEFAULT);
+       CHECK(dataset_id, FAIL, "H5Dcreate");
+
+       for(i=0; i<F2_DIM0; i++)
+           for(j=0; j<F2_DIM1; j++)
+               data[i][j]=i*10+j;
+
+       /* Write data to the new dataset */
+       ret = H5Dwrite(dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+                H5P_DEFAULT, data);
+       CHECK(ret, FAIL, "H5Dwrite");
+
+       if(ret_did != NULL)
+           *ret_did = dataset_id;
+
+       /* Terminate access to the data space. */
+       ret = H5Sclose(dataspace_id);
+       CHECK(ret, FAIL, "H5Sclose");
+    }
+
+    /* Create a group in the second file open */
+    {
+        hid_t   gid1, gid2, gid3;
+        gid1 = H5Gcreate(fid2, "/group", 0);
+        if(ret_gid1 != NULL)
+            *ret_gid1 = gid1;
+
+        gid2 = H5Gopen(fid2, "/group");
+        if(ret_gid2 != NULL)
+            *ret_gid2 = gid2;
+
+        gid3 = H5Gopen(fid2, "/group");
+        if(ret_gid3 != NULL)
+            *ret_gid3 = gid3;
+    }
+
+    /* Check reference counts of file IDs and opened object IDs.
+     * The verification is hard-coded.  If in any case, this testing
+     * is changed, remember to check this part and update the macros.
+     */
+    {
+       ret = H5Fget_obj_count(fid1, H5F_OBJ_ALL, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_6, "H5Fget_obj_count");
+
+       ret = H5Fget_obj_count(fid1, H5F_OBJ_DATASET|H5F_OBJ_GROUP|
+                                H5F_OBJ_DATATYPE, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count");
+
+       ret = H5Fget_obj_count(fid2, H5F_OBJ_ALL, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_6, "H5Fget_obj_count");
+
+       ret = H5Fget_obj_count(fid2, H5F_OBJ_DATASET|H5F_OBJ_GROUP|
+                                H5F_OBJ_DATATYPE, &oid_count);
+       CHECK(ret, FAIL, "H5Fget_obj_count");
+       VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count");
+    }
+}
+
+/****************************************************************
+**
+**  test_obj_count_and_id(): test object count and ID list functions. 
+**
+****************************************************************/
+static void 
+test_obj_count_and_id(hid_t fid1, hid_t fid2, hid_t did, hid_t gid1, 
+			hid_t gid2, hid_t gid3)
+{
+    hid_t    fid3, fid4;
+    unsigned oid_count;
+    herr_t   ret;
+
+    /* Create two new files */
+    fid3 = H5Fcreate(FILE2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    CHECK(fid3, FAIL, "H5Fcreate");
+    fid4 = H5Fcreate(FILE3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+    CHECK(fid4, FAIL, "H5Fcreate");
+
+    /* test object count of all files IDs open */
+    ret = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_FILE, &oid_count);
+    CHECK(ret, FAIL, "H5Fget_obj_count");
+    VERIFY(oid_count, OBJ_ID_COUNT_4, "H5Fget_obj_count");
+
+    /* test object count of all dataset open */
+    ret = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_DATASET, &oid_count);
+    CHECK(ret, FAIL, "H5Fget_obj_count");
+    VERIFY(oid_count, OBJ_ID_COUNT_1, "H5Fget_obj_count");
+
+    /* test object count of all group open */
+    ret = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_GROUP, &oid_count);
+    CHECK(ret, FAIL, "H5Fget_obj_count");
+    VERIFY(oid_count, OBJ_ID_COUNT_3, "H5Fget_obj_count");
+
+    /* test object count of all datatype open */
+    ret = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_DATATYPE, &oid_count);
+    CHECK(ret, FAIL, "H5Fget_obj_count");
+    VERIFY(oid_count, OBJ_ID_COUNT_0, "H5Fget_obj_count");
+
+    /* test object count of all objects currently open */
+    ret = H5Fget_obj_count(H5F_OBJ_ALL, H5F_OBJ_ALL, &oid_count);
+    CHECK(ret, FAIL, "H5Fget_obj_count");
+    VERIFY(oid_count, OBJ_ID_COUNT_8, "H5Fget_obj_count");
+
+    {
+        hid_t      *oid_list;
+        unsigned   i;
+        H5I_type_t id_type;
+
+        oid_list = (hid_t*)calloc(oid_count, sizeof(hid_t));
+        if(oid_list != NULL) {
+	    ret = H5Fget_obj_ids(H5F_OBJ_ALL, H5F_OBJ_ALL, oid_list);
+	    CHECK(ret, FAIL, "H5Fget_obj_ids");
+        }
+
+        for(i=0; i<oid_count; i++) {
+	    id_type = H5Iget_type(oid_list[i]);
+	    switch(id_type) {
+	        case H5I_FILE:
+		    if(oid_list[i]!=fid1 && oid_list[i]!=fid2 &&
+			oid_list[i]!=fid3 && oid_list[i]!=fid4) {
+			ret = FAIL;
+			CHECK(ret, FAIL, "H5Fget_obj_ids");
+		    }
+		    break;
+	        case H5I_GROUP:
+                    if(oid_list[i]!=gid1 && oid_list[i]!=gid2 &&
+                        oid_list[i]!=gid3) {
+			ret = FAIL;
+                        CHECK(ret, FAIL, "H5Fget_obj_ids");
+                    }   
+		    break;
+	        case H5I_DATASET:
+	 	    VERIFY(oid_list[i], did, "H5Fget_obj_ids");
+		    break;
+		default:
+		    ret = FAIL;
+                    CHECK(ret, FAIL, "H5Fget_obj_ids");
+	    }
+        }	
+
+        free(oid_list);
+    }
+
+    /* close the two new files */
+    ret = H5Fclose(fid3);
+    CHECK(fid3, FAIL, "H5Fclose");
+    ret = H5Fclose(fid4);
+    CHECK(fid4, FAIL, "H5Fclose");
+}
+
 /****************************************************************
 **
 **  test_file(): Main low-level file I/O test routine.
@@ -354,8 +844,9 @@ test_file(void)
     /* Output message about test being performed */
     MESSAGE(5, ("Testing Low-Level File I/O\n"));
 
-    test_file_create();		/* Test file creation (also creation templates) */
+    test_file_create();		/* Test file creation(also creation templates)*/
     test_file_open();		/* Test file opening */
+    test_file_close();          /* Test file close behavior */
 }				/* test_file() */
 
 
@@ -380,4 +871,3 @@ cleanup_file(void)
     remove(FILE2);
     remove(FILE3);
 }
-