/*
class RegexMarshalByRefWrapper

    by: Shawn A. Van Ness
    rev: 2002.05.27

This simple little C# class is a remoteable wrapper around the 
System.Text.RegularExpressions.Regex class.  Usage looks something like this:

    object[] reCtorArgs = new object[] { "[A-Za-z]+[A-Za-z0-9]*", RegexOptions.Compiled };

    RegexMarshalByRefWrapper re = (RegexMarshalByRefWrapper)ad2.CreateInstanceAndUnwrap(
        "ThisAssembly", "RegexMarshalByRefWrapper", false, BindingFlags.Default, 
        null, reCtorArgs, null, null, null);

    re.IsMatch( "foo");

Motivation:  When using RegexOptions.Compiled, the code generated (via 
Reflection.Emit) is never garbage-collectable by the system.  The only way to 
unload code in .NET is to unload an appdomain.  But the Regex class is 
[Serializable], so it will be marshaled by value back into our own appdomain 
if we naively try to instantiate a Regex remotely.

A remoteable wrapper is needed -- all remoteable objects must derive from 
MarshalByRefObject, and because C#/.NET does not support multiple inheritance, 
we can't just simply derive from Regex, too.  :(  Oh well, the only difference 
between is-a and has-a relationships is a bit of typing!  So here we go...
*/

using System;
using System.Text.RegularExpressions;

public class RegexMarshalByRefWrapper : MarshalByRefObject
{
    private Regex _re;
    
    public RegexMarshalByRefWrapper( string pattern)
    { _re = new Regex( pattern); }
    public RegexMarshalByRefWrapper( string pattern, RegexOptions options)
    { _re = new Regex( pattern, options); }

    public RegexOptions Options
    { get { return _re.Options; } }
    public bool RightToLeft
    { get { return _re.RightToLeft; } }

    public string[] GetGroupNames()
    { return _re.GetGroupNames(); }
    public int[] GetGroupNumbers()
    { return _re.GetGroupNumbers(); }

    public string GroupNameFromNumber( int i)
    { return _re.GroupNameFromNumber( i); }
    public int GroupNumberFromName( string name)
    { return _re.GroupNumberFromName( name); }

    public bool IsMatch( string input)
    { return _re.IsMatch( input); }
    public bool IsMatch( string input, int startat)
    { return _re.IsMatch( input, startat); }

    public Match Match( string input)
    { return _re.Match( input); }
    public Match Match( string input, int startat)
    { return _re.Match( input, startat); }
    public Match Match( string input, int startat, int length)
    { return _re.Match( input, startat, length); }

    public MatchCollection Matches( string input)
    { return _re.Matches( input); }
    public MatchCollection Matches( string input, int startat)
    { return _re.Matches( input, startat); }

    public string Replace( string input, MatchEvaluator evaluator)
    { return _re.Replace( input, evaluator); }
    public string Replace( string input, string replacement)
    { return _re.Replace( input, replacement); }
    public string Replace( string input, MatchEvaluator evaluator, int count)
    { return _re.Replace( input, evaluator, count); }
    public string Replace( string input, string replacement, int count)
    { return _re.Replace( input, replacement, count); }
    public string Replace( string input, MatchEvaluator evaluator, int count, int startat)
    { return _re.Replace( input, evaluator, count, startat); }
    public string Replace( string input, string replacement, int count, int startat)
    { return _re.Replace( input, replacement, count, startat); }

    public string[] Split( string input)
    { return _re.Split( input); }
    public string[] Split( string input, int count)
    { return _re.Split( input, count); }
    public string[] Split( string input, int count, int startat)
    { return _re.Split( input, count, startat); }

    public override string ToString()
    { return _re.ToString(); }
}