def library_include(parameters, config):
	markdown_lines = []
	
	policy_filename = parameters[0] + ".json"
	policy_json = config.get(policy_filename)
	html_name = config.get("context_current_html")
	if policy_json == None:
		policy_path = config["project_directory"] + "/_json/" + policy_filename
		if not os.path.exists(policy_path):
			print "cfdoc_syntaxmap:library_include: File does not exist: " + policy_path
			return markdown_lines
		
		policy_json = json.load(open(policy_path, 'r'))
		config[policy_filename] = policy_json
		
	# for all bundles and bodies...
	for key in policy_json.keys():
		element_list = policy_json[key]
		
		current_type = None
		for element in element_list:
			namespace = element["namespace"]
			if namespace == "default":
				namespace = None
			name = element["name"]
			element_type = element.get("bundleType")
			if element_type == None:
				element_type = element.get("bodyType")
			if element_type == None:
				print "cfdoc_syntaxmap:library_include: element without type: " + name
				continue
				
			# start a new block for changed types
			# Assumes that bundles and bodies are grouped by type in library.cf
			if element_type != current_type:
				current_type = element_type
				markdown_lines.append("### " + current_type + " " + key + "\n")
				markdown_lines.append("\n")
		
			prototype = name
			if namespace:
				prototype = namespace + ":" + prototype
				
			markdown_lines.append("#### " + prototype + "\n")
			link_target = prototype + "()"
			if not namespace:
				link_target = parameters[0] + ":" + link_target
			linkresolver.addLinkToMap("`" + prototype + "()`", link_target, html_name + "#" + prototype, config)
			markdown_lines.append("\n")
			
			code_lines = []
			documentation_lines = []
			documentation_dict = dict()
			
			try:
				source_path = config["project_directory"] + "/" + element["sourcePath"]
				source_file = open(source_path, 'r')
				sourceLine = element["sourceLine"]
				sourceLines = source_file.readlines()
			except:
				print "cfdoc_syntaxmap:library_include: could not include code from " + name
			
			if len(sourceLines):
				# search up to include bundle/body declaration and comments in between
				headerLines = list()
				header_line = sourceLine - 1
				while header_line:
					line = sourceLines[header_line].lstrip()
					header_line -= 1
					headerLines.insert(0, line) # aka prepend
					if key == "bundles" and line.find("bundle ") == 0:
						break
					if key == "bodies" and line.find("body ") == 0:
						break
				
				# scan comments for doxygen-style documentation
				if len(headerLines):
					current_tag = None
					current_param = None
					current_line = ""
					for headerLine in headerLines:
						if headerLine.find("#") != 0:
							continue
							
						headerLine = headerLine[1:].lstrip().rstrip()
						if headerLine.find("@") == 0:
							current_param = None
							headerLine = headerLine[1:]
							current_tag = headerLine[:headerLine.find(" ")]
							headerLine = headerLine[len(current_tag) + 1:]
							documentation_dict[current_tag] = ""
							
						if current_tag == None:
							continue
						
						if current_tag == "param":
							if current_param == None:
								current_param = headerLine[:headerLine.find(" ")]
								headerLine = headerLine[len(current_param) + 1:]
								documentation_dict["param_" + current_param] = headerLine + "\n"
							else:
								documentation_dict["param_" + current_param] += headerLine + "\n"
						else:
							documentation_dict[current_tag] += headerLine + "\n"
							
					brief = documentation_dict.get("brief", "")
					if len(brief):
						documentation_lines.append("**Description:** ")
						documentation_lines.append(brief)
						documentation_lines.append("\n")
					return_doc = documentation_dict.get("return", "")
					if len(return_doc):
						documentation_lines.append("**Return value:** ")
						documentation_lines.append(return_doc)
						documentation_lines.append("\n")
				
				code_lines.append("\n```cf3\n")
				if len(headerLines):
					code_lines.append(headerLines[0])
					code_lines.append("{\n")
				while sourceLine < len(sourceLines):
					line = sourceLines[sourceLine]
					code_lines.append(line)
					# super-naive parser...
					if line.find("}") == 0:
						break
					sourceLine += 1
				code_lines.append("\n```\n")

			arguments = element["arguments"]
			argument_idx = 0
			argument_lines = []
			while argument_idx < len(arguments):
				if argument_idx == 0:
					prototype += "("
					argument_lines.append("**Arguments:**\n\n")
				argument = arguments[argument_idx]
				prototype += argument
				argument_line = "* `" + argument + "`"
				
				# if we have already found documentation for this, use it
				param_line = documentation_dict.get("param_" + argument)
				if param_line != None:
					argument_line += ": " + param_line
				# find out where the argument is being used
				elif key == "bundles":
					for promise_type in element["promiseTypes"]:
						promise_type_link = "`" + promise_type["name"] + "`"
						for context in promise_type["contexts"]:
							for promise in context["promises"]:
								promiser = promise["promiser"]
								if promiser.find("(" + argument + ")") != -1:
									argument_line += ", used as promiser of type " + promise_type_link
								else:
									argument_line += resolveAttribute(promise["attributes"], argument)
									if len(argument_line):
										argument_line += " of " + promise_type_link + " promiser *" + promiser + "*"
				elif key == "bodies":
					for context in element["contexts"]:
						argument_line += resolveAttribute(context["attributes"], argument)
				argument_line += "\n"
					
				argument_lines.append(argument_line)
				argument_idx += 1
				if argument_idx == len(arguments):
					prototype += ")"
				else:
					prototype += ", "
					
			markdown_lines.append("**Prototype:** `" + prototype + "`\n")
			markdown_lines.append("\n")
			if len(documentation_lines):
				markdown_lines.append(documentation_lines)
				markdown_lines.append("\n")
			if len(argument_lines):
				markdown_lines.append(argument_lines)
				markdown_lines.append("\n")
			if len(code_lines):
				markdown_lines.append(code_lines)
				markdown_lines.append("\n")
			markdown_lines.append("\n")
		
	if len(markdown_lines) == 0:
		print "cfdoc_syntaxmap:library_include: Failure to include " + parameters[0]
		
	return 	markdown_lines
def library_include(parameters, config):
	markdown_lines = []
	policy_filename = parameters[0] + ".json"
	policy_json = config.get(policy_filename)
	html_name = config.get("context_current_html")

	qa.LogProcessStart(config, "library_include: %s" % policy_filename)

	if policy_json == None:
		policy_path = config["project_directory"] + "/_json/" + policy_filename
		if not os.path.exists(policy_path):
			qa.Log(config, "File does not exist: " + policy_path)
			return markdown_lines
		
		policy_json = json.load(open(policy_path, 'r'))
		config[policy_filename] = policy_json
		
	# for all bundles and bodies...
	for key in policy_json.keys():
		element_list = policy_json[key]
		current_type = None
		for element in element_list:
			errorString = []
			ignore = False
			namespace = element["namespace"]
			if namespace == "default":
				namespace = None
			name = element["name"]
			element_type = element.get("bundleType")
			if element_type == None:
				element_type = element.get("bodyType")
			if element_type == None:
				qa.Log(config, "element without type: " + name)
				continue
				
			# start a new block for changed types
			# Assumes that bundles and bodies are grouped by type in library.cf
			print_type = False
			if element_type != current_type:
				current_type = element_type
				print_type = True
		
			prototype = name
			if namespace:
				prototype = namespace + ":" + prototype

			title = prototype
			link_target = prototype + "()"
			if not namespace:
				link_target = parameters[0] + ":" + link_target
			linkresolver.addLinkToMap(prototype + "()", link_target, html_name + "#" + prototype, config)
			
			code_lines = []
			documentation_lines = []
			documentation_dict = dict()
			sourceLines = []
			sourceLine = -1
			
			try:
				source_path = config["project_directory"] + "/" + element["sourcePath"]
				source_path = os.path.normpath(source_path)
				source_file = open(source_path, 'r')
				sourceLine = element["line"] - 1 # zero-based indexing
				sourceLines = source_file.readlines()[sourceLine:]
			except:
				qa.Log(config, "could not include code from " + name)
			
			if len(sourceLines):
				headerLines = list()
				code_lines.append("\n```cf3\n")
				code_lines.append(sourceLines[0])
				del sourceLines[0]
				in_code = False
				
				for line in sourceLines:
					if not in_code:
						line = line.lstrip()
						if line.find("{") == 0:
							in_code = True
						else:
							headerLines.append(line)
					if in_code:
						code_lines.append(line)
						# super-naive parser...
						if line.find("}") == 0:
							break
				code_lines.append("\n```\n")
				
				# scan comments for doxygen-style documentation
				if len(headerLines):
					current_tag = None
					current_param = None
					current_line = ""
					for headerLine in headerLines:
						if headerLine.find("#") != 0:
							continue
							
						headerLine = headerLine[1:].rstrip()
						# strip single whitespace, but maintain indentation
						if headerLine.find(" ") == 0:
							headerLine = headerLine[1:]
						if headerLine.lstrip().find("@") == 0:
							current_param = None
							headerLine = headerLine.lstrip()[1:]
							current_tag = headerLine
							tag_end = headerLine.find(" ")
							if tag_end != -1:
								current_tag = current_tag[:tag_end]
								headerLine = headerLine[tag_end + 1:]
							documentation_dict[current_tag] = ""
							
						if current_tag == None:
							continue
						if current_tag == "ignore":
							ignore = True
							break
						
						if current_tag == "param":
							if current_param == None:
								current_param = headerLine[:headerLine.find(" ")]
								headerLine = headerLine[len(current_param) + 1:]
								documentation_dict["param_" + current_param] = headerLine + "\n"
							else:
								documentation_dict["param_" + current_param] += headerLine + "\n"
						else:
							documentation_dict[current_tag] += headerLine + "\n"

					brief = documentation_dict.get("brief", None)
					if brief:
						documentation_lines.append("**Description:** ")
						documentation_lines.append(brief)
						documentation_lines.append("\n")
					else:
						errorString.append("Missing description")
					return_doc = documentation_dict.get("return", None)
					if return_doc:
						documentation_lines.append("**Return value:** ")
						documentation_lines.append(return_doc)
						documentation_lines.append("\n")
				else: # no header lines
					errorString.append("No documentation")
			else: # no source lines
				errorString.append("No source code or unable to read source code")

			if ignore:
				continue
			arguments = element["arguments"]
			argument_idx = 0
			argument_lines = []
			while argument_idx < len(arguments):
				if argument_idx == 0:
					prototype += "("
					argument_lines.append("**Arguments:**\n\n")
				argument = arguments[argument_idx]
				prototype += argument
				argument_line = "* ```" + argument + "```"
				
				# if we have already found documentation for this, use it
				param_line = documentation_dict.get("param_" + argument)
				if param_line == None:
					errorString.append("No documentation for parameter %s" % argument)
				if param_line != None:
					argument_line += ": " + param_line
				# find out where the argument is being used
				elif key == "bundles":
					for promise_type in element["promiseTypes"]:
						promise_type_link = "`" + promise_type["name"] + "`"
						for context in promise_type["contexts"]:
							for promise in context["promises"]:
								promiser = promise["promiser"]
								if promiser.find("(" + argument + ")") != -1:
									argument_line += ", used as promiser of type " + promise_type_link
									argument_line += "\n"
								else:
									argument_line += resolveAttribute(promise["attributes"], argument)
									if len(argument_line):
										argument_line += " of " + promise_type_link + " promiser *" + promiser + "*"
					argument_line += "\n"
				elif key == "bodies":
					for context in element["contexts"]:
						argument_line += resolveAttribute(context["attributes"], argument)
					argument_line += "\n"
					
				argument_lines.append(argument_line)
				argument_idx += 1
				if argument_idx == len(arguments):
					prototype += ")"
				else:
					prototype += ", "
			
			if print_type:
				link_map = config["link_map"]
				if ("`body %s`" % current_type) in link_map:
					printable_type = "[%s]%s bodies" % (current_type, link_map["`body %s`" % current_type][0])
				elif ("`bundle %s`" % current_type) in link_map:
					printable_type = "[%s]%s bundles" % (current_type, link_map["`bundle %s`" % current_type][0])
				elif ("`%s`" % current_type) in link_map:
					printable_type = "[%s]%s %s" % (current_type, link_map["`%s`" % current_type][0], key)
				elif key == "bundles":
					printable_type = "%s [bundles][bundles]" % current_type
				else:
					printable_type = current_type
				markdown_lines.append("### %s\n" % printable_type)
				markdown_lines.append("\n")
			
			markdown_lines.append("#### " + title + " ####\n")
			markdown_lines.append("\n")
			markdown_lines.append("**Prototype:** `" + prototype + "`\n")
			markdown_lines.append("\n")
			if len(documentation_lines):
				markdown_lines.append(documentation_lines)
				markdown_lines.append("\n")
			if len(argument_lines):
				markdown_lines.append(argument_lines)
				markdown_lines.append("\n")
			if len(code_lines):
				markdown_lines.append("**Implementation:**\n")
				markdown_lines.append("\n")
				markdown_lines.append(code_lines)
				markdown_lines.append("\n")
			markdown_lines.append("\n")
			if len(errorString):
				locationString = "`in library `" + os.path.relpath(source_path) + "` (%d)" % sourceLine
				qa.LogMissingDocumentation(config, prototype, errorString, locationString)
				errorString = []

	if len(markdown_lines) == 0:
		qa.Log(config, "Failure to include " + parameters[0])
		
	return 	markdown_lines
def library_include(parameters, config):
    markdown_lines = []
    policy_filename = parameters[0] + ".json"
    policy_json = config.get(policy_filename)
    html_name = config.get("context_current_html")

    qa.LogProcessStart(config, "library_include: %s" % policy_filename)

    if policy_json == None:
        policy_path = config[
            "project_directory"] + "/_generated/" + policy_filename
        if not os.path.exists(policy_path):
            qa.Log(config, "File does not exist: " + policy_path)
            return markdown_lines

        policy_json = json.load(open(policy_path, 'r'))
        config[policy_filename] = policy_json

    # for all bundles and bodies...
    for key in policy_json.keys():
        element_list = policy_json[key]
        current_type = None
        for element in element_list:
            errorString = []
            ignore = False
            namespace = element["namespace"]
            if namespace == "default":
                namespace = None
            name = element["name"]
            element_type = element.get("bundleType")
            if element_type == None:
                element_type = element.get("bodyType")
            if element_type == None:
                qa.Log(config, "element without type: " + name)
                continue

            # start a new block for changed types
            # Assumes that bundles and bodies are grouped by type in library.cf
            print_type = False
            if element_type != current_type:
                current_type = element_type
                print_type = True

            prototype = name
            if namespace:
                prototype = namespace + ":" + prototype

            title = prototype
            link_target = prototype + "()"
            if not namespace:
                link_target = parameters[0] + ":" + link_target
            linkresolver.addLinkToMap(prototype + "()", link_target,
                                      html_name + "#" + prototype, config)

            code_lines = []
            documentation_lines = []
            documentation_dict = dict()
            sourceLines = []
            sourceLine = -1

            try:
                source_path = element["sourcePath"]
                source_path = os.path.normpath(source_path)
                source_file = open(source_path, 'r')
                sourceLine = element["line"] - 1  # zero-based indexing
                sourceLines = source_file.readlines()[sourceLine:]
            except:
                qa.Log(
                    config,
                    "could not include code for element %s - check %s" %
                    (name, source_path))

            if len(sourceLines):
                headerLines = list()
                code_lines.append("\n```cf3\n")
                code_lines.append(sourceLines[0])
                del sourceLines[0]
                in_code = False

                for line in sourceLines:
                    if not in_code:
                        line = line.lstrip()
                        if line.find("{") == 0:
                            in_code = True
                        else:
                            headerLines.append(line)
                    if in_code:
                        code_lines.append(line)
                        # super-naive parser...
                        if line.find("}\n") == 0:
                            break
                code_lines.append("\n```\n")

                # scan comments for doxygen-style documentation
                if len(headerLines):
                    current_tag = None
                    current_param = None
                    current_line = ""
                    for headerLine in headerLines:
                        if headerLine.find("#") != 0:
                            continue

                        headerLine = headerLine[1:].rstrip()
                        # strip single whitespace, but maintain indentation
                        if headerLine.find(" ") == 0:
                            headerLine = headerLine[1:]
                        if headerLine.lstrip().find("@") == 0:
                            current_param = None
                            headerLine = headerLine.lstrip()[1:]
                            current_tag = headerLine
                            tag_end = headerLine.find(" ")
                            if tag_end != -1:
                                current_tag = current_tag[:tag_end]
                                headerLine = headerLine[tag_end + 1:]
                            documentation_dict[current_tag] = ""

                        if current_tag == None:
                            continue
                        if current_tag == "ignore":
                            ignore = True
                            break

                        if current_tag == "param":
                            if current_param == None:
                                current_param = headerLine[:headerLine.find(" "
                                                                            )]
                                headerLine = headerLine[len(current_param) +
                                                        1:]
                                documentation_dict[
                                    "param_" +
                                    current_param] = headerLine + "\n"
                            else:
                                documentation_dict[
                                    "param_" +
                                    current_param] += headerLine + "\n"
                        else:
                            documentation_dict[
                                current_tag] += headerLine + "\n"

                    brief = documentation_dict.get("brief", None)
                    if brief:
                        documentation_lines.append("**Description:** ")
                        documentation_lines.append(brief)
                        documentation_lines.append("\n")
                    else:
                        errorString.append("Missing description")
                    return_doc = documentation_dict.get("return", None)
                    if return_doc:
                        documentation_lines.append("**Return value:** ")
                        documentation_lines.append(return_doc)
                        documentation_lines.append("\n")
                else:  # no header lines
                    errorString.append("No documentation")
            else:  # no source lines
                errorString.append(
                    "No source code or unable to read source code")

            if ignore:
                continue
            arguments = element["arguments"]
            argument_idx = 0
            argument_lines = []
            while argument_idx < len(arguments):
                if argument_idx == 0:
                    prototype += "("
                    argument_lines.append("**Arguments:**\n\n")
                argument = arguments[argument_idx]
                prototype += argument
                argument_line = "* ```" + argument + "```"

                # if we have already found documentation for this, use it
                param_line = documentation_dict.get("param_" + argument)
                if param_line == None:
                    errorString.append("No documentation for parameter %s" %
                                       argument)
                if param_line != None:
                    argument_line += ": " + param_line
                # find out where the argument is being used
                elif key == "bundles":
                    for promise_type in element["promiseTypes"]:
                        promise_type_link = "`" + promise_type["name"] + "`"
                        for context in promise_type["contexts"]:
                            for promise in context["promises"]:
                                promiser = promise["promiser"]
                                if promiser.find("(" + argument + ")") != -1:
                                    argument_line += ", used as promiser of type " + promise_type_link
                                    argument_line += "\n"
                                else:
                                    argument_line += resolveAttribute(
                                        promise["attributes"], argument)
                                    if len(argument_line):
                                        argument_line += " of " + promise_type_link + " promiser *" + promiser + "*"
                    argument_line += "\n"
                elif key == "bodies":
                    for context in element["contexts"]:
                        argument_line += resolveAttribute(
                            context["attributes"], argument)
                    argument_line += "\n"

                argument_lines.append(argument_line)
                argument_idx += 1
                if argument_idx == len(arguments):
                    prototype += ")"
                else:
                    prototype += ", "

            if print_type:
                link_map = config["link_map"]
                if ("`body %s`" % current_type) in link_map:
                    printable_type = "[%s]%s bodies" % (
                        current_type, link_map["`body %s`" % current_type][0])
                elif ("`bundle %s`" % current_type) in link_map:
                    printable_type = "[%s]%s bundles" % (
                        current_type,
                        link_map["`bundle %s`" % current_type][0])
                elif ("`%s`" % current_type) in link_map:
                    printable_type = "[%s]%s %s" % (
                        current_type, link_map["`%s`" % current_type][0], key)
                elif key == "bundles":
                    printable_type = "%s [bundles][bundles]" % current_type
                else:
                    printable_type = current_type
                markdown_lines.append("### %s\n" % printable_type)
                markdown_lines.append("\n")

            markdown_lines.append("#### " + title + " ####\n")
            markdown_lines.append("\n")
            markdown_lines.append("**Prototype:** `" + prototype + "`\n")
            markdown_lines.append("\n")
            if len(documentation_lines):
                markdown_lines.append(documentation_lines)
                markdown_lines.append("\n")
            if len(argument_lines):
                markdown_lines.append(argument_lines)
                markdown_lines.append("\n")
            if len(code_lines):
                markdown_lines.append("**Implementation:**\n")
                markdown_lines.append("\n")
                markdown_lines.append(code_lines)
                markdown_lines.append("\n")
            markdown_lines.append("\n")
            if len(errorString):
                locationString = "`in library `" + os.path.relpath(
                    source_path) + "` (%d)" % sourceLine
                qa.LogMissingDocumentation(config, prototype, errorString,
                                           locationString)
                errorString = []

    if len(markdown_lines) == 0:
        qa.Log(config, "Failure to include " + parameters[0])

    return markdown_lines