legacy/src/main/java/thredds/catalog/util/DeepCopyUtils.java
public static InvDataset copyDataset( InvDataset dataset, List<InvService> availableServices,
                                        boolean copyInheritedMetadataFromParents )
  {
    if ( dataset == null ) throw new IllegalArgumentException( "Dataset may not be null." );
    if ( availableServices == null ) throw new IllegalArgumentException( "List of available services may not be null.");

    InvDatasetImpl resultDs;
    // ToDo Deal with InvDatasetScan and its ilk.
    if ( dataset instanceof InvCatalogRef )
    {
      InvCatalogRef catRef = (InvCatalogRef) dataset;
      resultDs = new InvCatalogRef( null, catRef.getName(), catRef.getXlinkHref());
    } else {
      resultDs = new InvDatasetImpl( null, dataset.getName() );
    }
    resultDs.setID( dataset.getID() );

    resultDs.transferMetadata( (InvDatasetImpl) dataset, copyInheritedMetadataFromParents );

    // Only copy child InvAccess if the current dataset is not an InvCatalogRef.
    if ( !( dataset instanceof InvCatalogRef ) ) {
      String urlPath = ( (InvDatasetImpl) dataset ).getUrlPath();
      if ( urlPath != null )
        resultDs.setUrlPath( urlPath );
      else
      {
        for ( InvAccess curAccess : dataset.getAccess()) {
          InvAccess access = copyAccess( curAccess, resultDs, availableServices );
          if ( access != null ) resultDs.addAccess( access );
        }
      }
    }

    // Only recurse into child datasets if the current dataset is not an InvCatalogRef.
    if ( !( dataset instanceof InvCatalogRef ) ) {
      for ( InvDataset curDs : dataset.getDatasets() )
      {
        InvDatasetImpl curDsCopy = (InvDatasetImpl) copyDataset( curDs, availableServices, false );
        curDsCopy.setParent( resultDs );
        resultDs.addDataset( curDsCopy );
      }
    }

    return resultDs;
  }
public static InvDataset copyDataset( InvDataset dataset, List<InvService> availableServices,
                                        boolean copyInheritedMetadataFromParents )
  {
    if ( dataset == null ) throw new IllegalArgumentException( "Dataset may not be null." );
    if ( availableServices == null ) throw new IllegalArgumentException( "List of available services may not be null.");

    InvDatasetImpl resultDs;
    // ToDo Deal with InvDatasetScan and its ilk.
    if ( dataset instanceof InvCatalogRef )
    {
      InvCatalogRef catRef = (InvCatalogRef) dataset;
      resultDs = new InvCatalogRef( null, catRef.getName(), catRef.getXlinkHref());
    } else {
      resultDs = new InvDatasetImpl( null, dataset.getName() );
    }
    resultDs.setID( dataset.getID() );

    resultDs.transferMetadata( (InvDatasetImpl) dataset, copyInheritedMetadataFromParents );

    // Only copy child InvAccess if the current dataset is not an InvCatalogRef.
    if ( !( dataset instanceof InvCatalogRef ) ) {
      String urlPath = ( (InvDatasetImpl) dataset ).getUrlPath();
      if ( urlPath != null )
        resultDs.setUrlPath( urlPath );
      else
      {
        for ( InvAccess curAccess : dataset.getAccess()) {
          InvAccess access = copyAccess( curAccess, resultDs, availableServices );
          if ( access != null ) resultDs.addAccess( access );
        }
      }
    }

    // Only recurse into child datasets if the current dataset is not an InvCatalogRef.
    if ( !( dataset instanceof InvCatalogRef ) ) {
      for ( InvDataset curDs : dataset.getDatasets() )
      {
        InvDatasetImpl curDsCopy = (InvDatasetImpl) copyDataset( curDs, availableServices, false );
        curDsCopy.setParent( resultDs );
        resultDs.addDataset( curDsCopy );
      }
    }

    return resultDs;
  }
}