program define labvalch
*! NJC 1.1.0 12 July 2002
* NJC 1.0.1 6 April 2000
* NJC 1.0.0 13 January 2000
	version 7
	gettoken vallbl 0 : 0, parse(" ,")
	capture label list `vallbl'
	if _rc {
		di as err "`vallbl' not a value label"
		exit 498
	}

	syntax , [ From(numlist min=1 int) To(numlist min=1 int) /*
	*/ Swap(numlist min=2 max=2 int) DELETE(numlist min=1 int) List ]

	if "`swap'`from'`to'`delete'" == "" {
		di as txt "nothing to do?"
		exit 0
	}

	if "`swap'" != "" & "`from'`to'" != "" {
		di as err "may not combine swapping and mapping"
		exit 198
	}

	local nopts = ("`from'" != "") + ("`to'" != "")
	if `nopts' == 1 {
		di as err "from( ) must be combined with to( )"
		exit 198
	}

	local newline "_n"

	if "`swap'" != "" { /* swapping */
		tokenize `swap'
		forval i = 1/2 {
			local l`i' : label `vallbl' ``i''
			if `"`l`i''"' == "``i''" {
				di as err "`vallbl': no value label for ``i''"
				exit 498
			}
		}

		di _n as txt `"label def `vallbl' `1' `"`l2'"' "' _c
		di as txt `" `2' `"`l1'"', modify "'
                label def `vallbl' `1' `"`l2'"' `2' `"`l1'"', modify
		local newline
	}

	if "`from'`to'" != "" { /* mapping */
		local nfrom : word count `from'
		local nto : word count `to'

		if `nfrom' != `nto' {
			di as err "from( ) and to( ) should match one-one"
			exit 198
		}

		tokenize `from'
		forval i = 1 / `nfrom' {
			local l`i' : label `vallbl' ``i''
			if `"`l`i''"' == "``i''" {
				di as err "`vallbl': no value label for ``i''"
				exit 498
			}
			local t`i' : word `i' of `to'
			local args `"`args'`t`i'' `"`l`i''"' "'
		}

		di _n as txt `"label def `vallbl' `args', modify"'
		label def `vallbl' `args', modify
		local newline
	}

	if "`delete'" != "" {
		local args
		tokenize `delete'
		local ndelete : word count `delete'
		forval i = 1 / `ndelete' {
			local l`i' : label `vallbl' ``i''
			if `"`l`i''"' == "``i''" {
				local msg "`msg'``i'' "
			}
			else local args `"`args'``i'' "" "'
		}
		if `"`args'"' != "" {
			di `newline' as txt `"label def `vallbl' `args', modify"'
			label def `vallbl' `args', modify
			local newline
		}
		if `"`msg'"' != "" {
			local wc : word count `msg'
			local s = cond(`wc' > 1, "s", "")
			di `newline' as txt /*
			*/ "note: `vallbl': label`s' for `msg'not defined"
		}
	}

	if "`list'" != "" {
		di
		label li `vallbl'
	}
end

/*
Note:

We delete a label for # by

label def lblname # "" , modify

Any subsequent

label def lblname # "" , modify

redefines the label as an empty string. So we need to trap that.

*/