<!--- Check to see which tag mode we are running. --->
<cfif (THISTAG.ExecutionMode EQ "Start")>

	<!--- Define attributes. --->
	<cfparam name="ATTRIBUTES.Text" type="string" />
	<cfparam name="ATTRIBUTES.Pattern" type="string" />
	<cfparam name="ATTRIBUTES.ReturnVariable" type="variablename" />

<cfelse>

	<!---
		Create the content for the method. When we do this, we
		have to replace the generic name of the function with
		a name to be used internally to this tag.
	--->
	<cfsavecontent variable="strMethod">
		<cfoutput>
			#("<" & "cfscript>")#
				#REReplaceNoCase(
					THISTAG.GeneratedContent,
					"function\s*\(",
					"function $(",
					"one"
					)#
			#("</" & "cfscript>")#
		</cfoutput>
	</cfsavecontent>

	<!--- Get a temporary file. --->
	<cfset strMethodFile = GetTempFile(
		ExpandPath( "/" ),
		"rereplace"
		) />

	<!--- Write the method to disk. --->
	<cffile
		action="write"
		file="#strMethodFile#"
		output="#strMethod#"
		/>

	<!--- Include the file. --->
	<cfinclude template="/#GetFileFromPath( strMethodFile )#" />

	<!---
		Now that the file has been include and compiled in the
		context of this tag, delete the temporary method file.
	--->
	<cffile
		action="delete"
		file="#strMethodFile#"
		/>


	<!--- Create a Java pattern based on the given expression. --->
	<cfset objPattern = CreateObject( "java", "java.util.regex.Pattern" ).Compile(
		JavaCast( "string", ATTRIBUTES.Pattern )
		) />

	<!--- Get the pattern matcher. --->
	<cfset objMatcher = objPattern.Matcher(
		JavaCast( "string", ATTRIBUTES.Text )
		) />

	<!--- Create a string buffer to hold the updated text. --->
	<cfset objBuffer = CreateObject( "java", "java.lang.StringBuffer" ).Init() />


	<!---
		Get the argument names for the temp method. Since we
		are passing the arguments by name, we need to match
		them up to the groups.
	--->
	<cfset arrParameters = GetMetaData( $ ).Parameters />


	<!--- Loop over the matches. --->
	<cfloop condition="#objMatcher.Find()#">

		<!---
			Build up the argument collection that will be passed
			to the temp replace method.
		--->
		<cfset objArguments = {} />

		<!--- Set the complete string match. --->
		<cfset objArguments[ arrParameters[ 1 ].Name ] = objMatcher.Group() />

		<!--- Add each group to arguments. --->
		<cfloop
			index="intGroup"
			from="1"
			to="#objMatcher.GroupCount()#"
			step="1">

			<!--- Set the argument. --->
			<cfset objArguments[ arrParameters[ intGroup + 1 ].Name ] = objMatcher.Group( JavaCast( "int", intGroup ) ) />

			<!---
				Check to see if it was found. If not, then set as
				empty string. We need to do this because there is
				no way to say that the arguments are not required.
			--->
			<cfif NOT StructKeyExists( objArguments, arrParameters[ intGroup + 1 ].Name )>

				<!---
					Group was not matched. Send to ColdFusion temp
					method as the empty string.
				--->
				<cfset objArguments[ arrParameters[ intGroup + 1 ].Name ] = "" />

			</cfif>

		</cfloop>


		<!--- Get the new replace content. --->
		<cfset strNewContent = $(
			ArgumentCollection = objArguments
			) />


		<!---
			Now, append the new content to the buffer. This will
			add not only the replacement content but also the
			rest of the text since the last match. When we do
			this, we have to be sure to escape back-references.
		--->
		<cfset objMatcher.AppendReplacement(
			objBuffer,
			REReplace( strNewContent, "([\$\\])", "\\\1", "all" )
			) />

	</cfloop>


	<!--- Add the rest of the unmatched content. --->
	<cfset objMatcher.AppendTail( objBuffer ) />


	<!---
		Store the fully updated content in the return variable
		of the CALLER scope.
	--->
	<cfset CALLER[ ATTRIBUTES.ReturnVariable ] = objBuffer.ToString() />

	<!---
		Reset the generated content. We don't want the body of
		the tag to show the method details.
	--->
	<cfset THISTAG.GeneratedContent = "" />

</cfif>