def fully_qualified_name(entry):
  """
  Calculates the fully qualified name for an entry by walking the path
  to the root node.

  Args:
    entry: a BeautifulSoup Tag corresponding to an <entry ...> XML node,
           or a <clone ...> XML node.

  Raises:
    ValueError: if entry does not correspond to one of the above XML nodes

  Returns:
    A string with the full name, e.g. "android.lens.info.availableApertureSizes"
  """

  filter_tags = ['namespace', 'section']
  parents = [i['name'] for i in entry.parents if i.name in filter_tags]

  if entry.name == 'entry':
    name = entry['name']
  elif entry.name == 'clone':
    name = entry['entry'].split(".")[-1] # "a.b.c" => "c"
  else:
    raise ValueError("Unsupported tag type '%s' for element '%s'" \
                        %(entry.name, entry))

  parents.reverse()
  parents.append(name)

  fqn = ".".join(parents)

  return fqn