def mono_get_file_table(packageversion, d):
	# The packageversion is currently ignored, but might be used in the future
	# if more than one mono version is available and different versions
	# need to use different tables

 	import bb, sys, os, glob, commands
	curdir = os.path.dirname( bb.data.getVar('FILE', d, 1)  )
	if curdir not in sys.path: sys.path.append( curdir )
	from mono_files import debian_mono_file_table
	
	# mono-jay is not being built (for all platforms at least)
	IGNORE = ("mono-jay", )
	file_table = [
	    # Standard package
	    {"name": "mono-doc"},
	    
	    # Virtual packages
	    {"name": "mono"},
	    {"name": "mono-runtime"},
	    
	    # Not provided by Debian:
	    {"name": "libnunit2.2-cil",
	     "patterns": [
	       "/usr/lib/mono/gac/nunit.*/2.2.*",
	       "/usr/lib/mono/1.0/nunit.*.dll",
	       "/usr/lib/pkgconfig/mono-nunit.pc",
	      ],
	      "assemblies": [
	       ("nunit.core", "2.2.0.0"),
	       ("nunit.framework", "2.2.0.0"),
	       ("nunit.util", "2.2.0.0"),
	       ("nunit.mocks", "2.2.8.0"),
	      ],
	    },
	    {"name": "libmono-cecil0.5-cil",
	     "patterns": [
	      "/usr/lib/mono/gac/Mono.Cecil/0.5.*",
	     ],
	     "assemblies": [
	      ("Mono.Cecil", "0.5.*"),
	     ],
	    },
	    {"name": "libmono-db2-1.0-cil",
	     "patterns": [
	      "/usr/lib/mono/gac/IBM.Data.DB2/1.0*",
	      "/usr/lib/mono/1.0/IBM.Data.DB2.dll",
	     ],
	     "assemblies": [
	      ("IBM.Data.DB2", "1.0*"),
	     ],
	    },
	] + debian_mono_file_table
	
	file_table = [e for e in file_table
		if not (e.has_key("name") and e["name"] in IGNORE)]
	
	return file_table

def mono_find_provides_and_requires(files, d):
	provides = []
	requires = []
	
	import bb, os, commands
	
	pathprefix = "export PATH=%s; export LANG=; export LC_ALL=; " % bb.data.getVar('PATH', d, 1)
	for filename in files:
		if not filename.endswith(".dll") and not filename.endswith(".exe"):
			continue
		if not os.path.isfile(filename) or os.path.islink(filename):
			continue
		
		## Provides
		name, version = None, None
		
		ret, result = commands.getstatusoutput("%smonodis --assembly '%s'" % (pathprefix, filename))
		if ret:
			bb.error("raw_provides_and_requires: monodis --assembly '%s' failed, dependency information will be inaccurate" % filename)
			continue
		for line in result.splitlines():
			if not ":" in line: continue
			key, value = line.split(":", 1)
			if key.strip() == "Name":
				name = value.strip()
			elif key.strip() == "Version":
				version = value.strip()
		if name is not None and version is not None:
			if (name, version) not in provides:
				provides.append( (name, version) )
	
		## Requires
		name, version = None, None
		ret, result = commands.getstatusoutput("%smonodis --assemblyref '%s'" % (pathprefix, filename))
		if ret:
			bb.error("raw_provides_and_requires: monodis --assemblyref '%s' failed, dependency information will be inaccurate" % filename)
			continue
		for line in result.splitlines():
			if not "=" in line: continue
			key, value = line.split("=", 1)
			if ":" in key and key.split(":",1)[1].strip() == "Version":
				version = value.strip()
			elif key.strip() == "Name":
				name = value.strip()
        		if name is not None and version is not None:
				if (name, version) not in requires:
					requires.append( (name, version) )
				name, version = None, None
	
	# Remove everything from requires that's already in provides as it's not actually required
	# to be provided externally
	requires = [e for e in requires if not e in provides]
	return provides, requires

python mono_do_clilibs() {
	import bb, os, re, os.path

	exclude_clilibs = bb.data.getVar('EXCLUDE_FROM_CLILIBS', d, 0)
	if exclude_clilibs:
		bb.note("not generating clilibs")
		return
		
	lib_re = re.compile("^lib.*\.so")
	libdir_re = re.compile(".*/lib$")

	packages = bb.data.getVar('PACKAGES', d, 1)

	workdir = bb.data.getVar('WORKDIR', d, 1)
	if not workdir:
		bb.error("WORKDIR not defined")
		return

	staging = bb.data.getVar('STAGING_DIR', d, 1)
	if not staging:
		bb.error("STAGING_DIR not defined")
		return

	pkgdest = bb.data.getVar('PKGDEST', d, 1)

	clilibs_dir = os.path.join(staging, "clilibs")
	bb.mkdirhier(clilibs_dir)

	provides, requires = {}, {}
	private_libs = bb.data.getVar('PRIVATE_CLILIBS', d, 1)
	for pkg in packages.split():
		bb.debug(2, "calculating clilib provides for %s" % pkg)

		files_to_check = []
		top = os.path.join(pkgdest, pkg)
		for root, dirs, files in os.walk(top):
			for file in files:
				path = os.path.join(root, file)
				if file.endswith(".exe") or file.endswith(".dll"):
					files_to_check.append( path )
		provides[pkg], requires[pkg] = mono_find_provides_and_requires(files_to_check, d)
		clilibs_file = os.path.join(clilibs_dir, pkg + ".list")
		if os.path.exists(clilibs_file):
			os.remove(clilibs_file)
		if len(provides[pkg]) > 0:
			fd = open(clilibs_file, 'w')
			for s in provides[pkg]:
				fd.write(" ".join(s) + '\n')
			fd.close()

	clilib_provider = {}
	list_re = re.compile('^(.*)\.list$')
	for file in os.listdir(clilibs_dir):
		m = list_re.match(file)
		if m:
			dep_pkg = m.group(1)
			fd = open(os.path.join(clilibs_dir, file))
			lines = fd.readlines()
			fd.close()
			for l in lines:
				clilib_provider[tuple(l.rstrip().split())] = dep_pkg

	for pkg in packages.split():
		bb.debug(2, "calculating clilib requirements for %s" % pkg)

		deps = []
		for n in requires[pkg]:
			if n in clilib_provider.keys():
				dep_pkg = clilib_provider[n]

				if dep_pkg == pkg:
					continue
				
				if not dep_pkg in deps:
					deps.append(dep_pkg)
			else:
				bb.note("Couldn't find CLI library provider for %s" % (n,))

		deps_file = os.path.join(pkgdest, pkg + ".clilibdeps")
		if os.path.exists(deps_file):
			os.remove(deps_file)
		if len(deps) > 0:
			fd = open(deps_file, 'w')
			for dep in deps:
				fd.write(dep + '\n')
			fd.close()
}

def mono_after_parse(d):
	import bb
	# Insert mono_do_clilibs into PACKAGEFUNCS
	# Needs to be called after populate_packages, but before read_shlibdeps
	PACKAGEFUNCS = bb.data.getVar("PACKAGEFUNCS", d, 1)
	if PACKAGEFUNCS:
		PACKAGEFUNCS = PACKAGEFUNCS.split()
		if "read_shlibdeps" in PACKAGEFUNCS:
			i = PACKAGEFUNCS.index("read_shlibdeps")
			PACKAGEFUNCS.insert(i, "mono_do_clilibs")
		elif "populate_packages" in PACKAGEFUNCS:
			i = PACKAGEFUNCS.index("populate_packages")
			PACKAGEFUNCS.insert(i+1, "mono_do_clilibs")
		bb.data.setVar("PACKAGEFUNCS", " ".join(PACKAGEFUNCS), d)

python () {
    mono_after_parse(d)
}