docs: def retrieve(pdb_id, cache_dir = None, bio_cache = None):
          '''Creates a PDBML object by using a cached copy of the files if they exists or by retrieving the files from the RCSB.'''
  
          pdb_contents = None
          xml_contents = None
          pdb_id = pdb_id.upper()
  
          if bio_cache:
              pdb_contents = bio_cache.get_pdb_contents(pdb_id)
              xml_contents = bio_cache.get_pdbml_contents(pdb_id)
  
          if cache_dir:
              if not pdb_contents:
                  # Check to see whether we have a cached copy of the PDB file
                  filename = os.path.join(cache_dir, "%s.pdb" % pdb_id)
                  if os.path.exists(filename):
                      pdb_contents = read_file(filename)
  
              if not xml_contents:
                  # Check to see whether we have a cached copy of the XML file
                  filename = os.path.join(cache_dir, "%s.xml" % pdb_id)
                  if os.path.exists(filename):
                      xml_contents = read_file(filename)
  
          # Get any missing files from the RCSB and create cached copies if appropriate
          if not pdb_contents:
              pdb_contents = rcsb.retrieve_pdb(pdb_id)
              if cache_dir:
                  write_file(os.path.join(cache_dir, "%s.pdb" % pdb_id), pdb_contents)
  
          if not xml_contents:
              xml_contents = rcsb.retrieve_xml(pdb_id)
              if cache_dir:
                  write_file(os.path.join(cache_dir, "%s.xml" % pdb_id), xml_contents)
  
          # Return the object
          handler = PDBML(xml_contents, pdb_contents, bio_cache = bio_cache, pdb_id = pdb_id)
          xml.sax.parseString(xml_contents, handler)
          return handler