*! NJC 1.1.0 8 Oct 2002
* NJC 1.0.0 1 Oct 2002
* some ideas from -rsquare- P. Ender and R. von Eyden 1.1 2/12/02
* all tabs mapped to 4 spaces
program define allpossible
    version 7.0

    * process syntax
    gettoken cmd 0 : 0
    syntax varlist(min=2 numeric ts) [aw fw iw pw] [if] [in] , /*
    */ [ ECLASS(str) RCLASS(str) NPMAX(int -1) * Format(str)   /*
    */ CELLWidth(int 12) Detail ]

    marksample touse
    qui count if `touse'
    if r(N) == 0 {
        error 2000
    }

    if "`eclass'`rclass'" == "" {
        di as err "must specify at least one of eclass() or rclass()"
	exit 198
    }
    if "`rclass'" != "" {
    	local nr : word count `rclass'
	if `nr' < 2 {
	    di as err "rclass() invalid"
	    exit 198
	}
	tokenize `rclass'
	local rprog "qui `1'"
	mac shift
	local rclass `*'
    }

    tokenize `varlist'
    local response `1'
    macro shift
    local rest `*'
    local np : word count `rest'

    local npmax = cond(`npmax' > 0 , min(`npmax',`np', 6), `np')
    local nfits = 0
    forval i = 0 / `npmax' {
        local nfits = `nfits' + comb(`np',`i')
    }
    qui count
    if r(N) < `nfits' {
        di as err "sorry: # of observations should be at least `nfits'"
        exit 198
    }

    * wire in response and apply any weights
    local cmd "`cmd' `response'"
    if "`detail'" != "" {
        local cmd "noisily `cmd'"
    }
    local etc "[`weight' `exp'] if `touse', `options'"

    * main loop, except that we break out somewhere before repetition
    qui while 1 {

        * no predictors
        `cmd' `etc'
	foreach s of local eclass {
            tempvar v`s'
            gen double `v`s'' = e(`s') in 1
            label var `v`s'' "`s'"
            local results "`results'`v`s'' "
	}

	if "`rclass'" != "" {
	    `rprog'
	    foreach s of local rclass {
	        tempvar v`s'
	        gen double `v`s'' = r(`s') in 1
	        label var `v`s'' "`s'"
	        local results "`results'`v`s'' "
	    }
        }

        tempvar predictors model
        gen str6 `predictors' = "(none)" in 1
        label var `predictors' "predictors"
        gen byte `model' = _n
        label var `model' "model"

        * one predictor
        local p = 1
        qui forval i = 1 / `np' {
            `cmd' ``i'' `etc'
            local p = `p' + 1
            foreach s of local eclass {
                replace `v`s'' = e(`s') in `p'
	    }
            if "`rclass'" != "" {
	        `rprog'
	        foreach s of local rclass {
	            replace `v`s'' = r(`s') in `p'
	        }
	    }
            replace `predictors' = "`i'" in `p'
        }

        if `npmax' == 1 {
            continue, break
        }

        * two predictors
        local npm1 = `np' - 1
        qui forval i = 1 / `npm1' {
            local j1 = `i' + 1
            forval j = `j1' / `np' {
                local p = `p' + 1
                `cmd' ``i'' ``j'' `etc'
                foreach s of local eclass {
                    replace `v`s'' = e(`s') in `p'
                }
		if "`rclass'" != "" {
	            `rprog'
	            foreach s of local rclass {
	                replace `v`s'' = r(`s') in `p'
	            }
	        }
                replace `predictors' = "`i' `j'" in `p'
            }
        }

        if `npmax' == 2 {
            continue, break
        }

        * three predictors
        local npm2 = `np' - 2
        qui forval i = 1 / `npm2' {
            local j1 = `i' + 1
            forval j = `j1' / `npm1' {
                local k1 = `j' + 1
                forval k = `k1' / `np' {
                    local p = `p' + 1
                    `cmd' ``i'' ``j'' ``k'' `etc'
                    foreach s of local eclass {
                        replace `v`s'' = e(`s') in `p'
                    }
                    if "`rclass'" != "" {
                        `rprog'
                         foreach s of local rclass {
                             replace `v`s'' = r(`s') in `p'
			 }
                    }
                    replace `predictors' = "`i' `j' `k'" in `p'
		}
            }
        }

        if `npmax' == 3 {
            continue, break
        }

        * four predictors
        local npm3 = `np' - 3
        qui forval i = 1 / `npm3' {
            local j1 = `i' + 1
            forval j = `j1' / `npm2' {
                local k1 = `j' + 1
                forval k = `k1' / `npm1' {
                    local l1 = `k' + 1
                    forval l = `l1' / `np' {
                        local p = `p' + 1
                        `cmd' ``i'' ``j'' ``k'' ``l'' `etc'
                        foreach s of local eclass {
                            replace `v`s'' = e(`s') in `p'
                        }
			if "`rclass'" != "" {
			    `rprog'
			    foreach s of local rclass {
			        replace `v`s'' = r(`s') in `p'
			    }
			}
		        replace `predictors' = "`i' `j' `k' `l'" in `p'
                    }
                }
            }
        }

        if `npmax' == 4 {
            continue, break
        }

        * five predictors
        local npm4 = `np' - 4
        qui forval i = 1 / `npm4' {
            local j1 = `i' + 1
            forval j = `j1' / `npm3' {
                local k1 = `j' + 1
                forval k = `k1' / `npm2' {
                    local l1 = `k' + 1
                    forval l = `l1' / `npm1' {
                        local m1 = `l' + 1
                        forval m = `m1' / `np' {
                            local p = `p' + 1
                            `cmd' ``i'' ``j'' ``k'' ``l'' ``m'' `etc'
                            foreach s of local eclass {
                                replace `v`s'' = e(`s') in `p'
                            }
			    if "`rclass'" != "" {
			        `rprog'
				foreach s of local rclass {
				    replace `v`s'' = r(`s') in `p'
				}
			    }
                            replace `predictors' = "`i' `j' `k' `l' `m'" in `p'
                        }
                    }
                }
            }
        }

        if `npmax' == 5 {
            continue, break
        }

        * six predictors
        local npm5 = `np' - 5
        quietly forval i = 1 / `npm5' {
            local j1 = `i' + 1
            forval j = `j1' / `npm4' {
                local k1 = `j' + 1
                forval k = `k1' / `npm3' {
                    local l1 = `k' + 1
                    forval l = `l1' / `npm2' {
                        local m1 = `l' + 1
                        forval m = `m1' / `npm1' {
                            local n1 = `m' + 1
                            forval n = `n1' / `np' {
                                local p = `p' + 1
                                `cmd' ``i'' ``j'' ``k'' ``l'' ``m'' ``n'' `etc'
                                foreach s of local eclass {
                                    replace `v`s'' = e(`s') in `p'
                                }
				if "`rclass'" != "" {
				    `rprog'
				    foreach s of local rclass {
				        replace `v`s'' = r(`s') in `p'
				    }
				}
                                replace `predictors' = "`i' `j' `k' `l' `m' `n'" in `p'
                            }
                        }
                    }
                }
            }
        }

        if `npmax' == 6 {
            continue, break
        }

     } /* main loop */

     * table output
     * integers mapped to strings to protect against decimal places
     qui foreach v of local results {
        capture assert `v' == int(`v')
        if _rc == 0 {
            tempvar v2
            gen str1 `v2' = ""
            replace `v2' = string(`v', "%9.0f")
            _crcslbl `v2' `v'
            local Results "`Results' `v2'"
        }
        else local Results "`Results' `v'"
     }

     if "`format'" == "" {
        local format "%4.3f"
     }


     tabdisp `model' in 1 / `p', c(`predictors' `Results') /*
     */ format(`format') cellwidth(`cellwidth')
     di
     forval i = 1 / `np' {
         di as res "  `i'" as text "{col 10}``i''"
     }

end