protected unsafe void StringToProperByteStar(string strOutput, byte *lpOutBuffer, ref int rnOutLen)
        {
            // if the output is legacy, then we need to shrink it from wide to narrow
            if (m_bLegacy)
            {
                byte[] baOut = EncConverters.GetBytesFromEncoding(CodePageOutput, strOutput, true);

                if (baOut.Length > rnOutLen)
                {
                    EncConverters.ThrowError(ErrStatus.OutputBufferFull);
                }
                rnOutLen = baOut.Length;
                ECNormalizeData.ByteArrToByteStar(baOut, lpOutBuffer);
            }
            else
            {
                int nLen = strOutput.Length * 2;
                if (nLen > (int)rnOutLen)
                {
                    EncConverters.ThrowError(ErrStatus.OutputBufferFull);
                }
                rnOutLen = nLen;
                rnOutLen = ECNormalizeData.StringToByteStar(strOutput, lpOutBuffer, rnOutLen, false);
            }
        }
        protected override unsafe void DoConvert
        (
            byte *lpInBuffer,
            int nInLen,
            byte *lpOutBuffer,
            ref int rnOutLen
        )
        {
            rnOutLen = 0;

            // we need to put it *back* into a string because the StreamWriter that will
            // ultimately write to the StandardInput uses a string. For now, the only user
            //  is Perl, which only supports Unicode to Unicode and so the data coming in
            //  will be UTF-16. So to put it back into a string, we just need to use this:
            var baDst = new byte[nInLen];

            ECNormalizeData.ByteStarToByteArr(lpInBuffer, nInLen, baDst);
            var enc      = Encoding.Unicode;
            var strInput = enc.GetString(baDst);

            // call the helper that calls the exe
            var strOutput = DoExeCall(strInput);

            if (Util.IsUnix)
            {
                Util.DebugWriteLine(this, "Got result from system call: " + strOutput);
                byte[] baOut2 = Encoding.Unicode.GetBytes(strOutput);  // easier to read
                Util.DebugWriteLine(this, Util.getDisplayBytes("Output UTF16LE", baOut2));

                string filepath = Path.Combine(Path.GetTempPath(), "returning.txt");
                Util.DebugWriteLine(this, "See " + filepath);
                TextWriter tw = new StreamWriter(filepath);
                tw.WriteLine("input: '" + strInput + "'");
                tw.WriteLine("output: '" + strOutput + "'");
                tw.Close();
            }

            // if there's a response...
            if (String.IsNullOrEmpty(strOutput))
            {
                return;
            }

            // put it in the output buffer
            rnOutLen = strOutput.Length * 2;
            rnOutLen = ECNormalizeData.StringToByteStar(strOutput, lpOutBuffer, rnOutLen, false);
        }
        protected override unsafe void DoConvert(byte *lpInBuffer, int nInLen, byte *lpOutBuffer, ref int rnOutLen)
        {
            // we need to put it *back* into a string for the lookup
            // [aside: I should probably override base.InternalConvertEx so I can avoid having the base
            //  class version turn the input string into a byte* for this call just so we can turn around
            //  and put it *back* into a string for our processing... but I like working with a known
            //  quantity and no other EncConverter does it that way. Besides, I'm afraid I'll break smtg ;-]
            var baIn = new byte[nInLen];

            ECNormalizeData.ByteStarToByteArr(lpInBuffer, nInLen, baIn);
            var caIn = Encoding.Unicode.GetChars(baIn);

            // here's our input string
            var strInput = new string(caIn);

            string strOutput = null;

            if (_bForward)
            {
                var bySpace = strInput.Split(_achSpace, StringSplitOptions.RemoveEmptyEntries);
                _breakIterator.SetText(strInput);
                var words = _breakIterator.Enumerate().ToList();
                if (bySpace.Length == words.Count)
                {
                    // it didn't do anything!
                    // if it is mandarin, this is probably expected and we can do this
                    if (_regexForMandarin.IsMatch(strInput))
                    {
                        strOutput = bySpace
                                    .SelectMany(word => word)
                                    .Aggregate <char, string>(null, (current, ch) => current + (ch + ConverterIdentifier));
                    }
                    else
                    {
                        strOutput = strInput;
                    }
                }
                else
                {
                    int nNumWords = words.Count - 1;
                    for (var i = 0; i < nNumWords; i++)
                    {
                        var word = words[i];
                        if (!String.IsNullOrEmpty(word) && (word != ConverterIdentifier))
                        {
                            strOutput += words[i] + ConverterIdentifier;
                        }
                    }
                    strOutput += words.Last();
                }
            }
            else
            {
                strOutput = strInput.Replace(ConverterIdentifier, null);
            }

            if (String.IsNullOrEmpty(strOutput))
            {
                return;
            }

            var nLen = strOutput.Length * 2;

            if (nLen > rnOutLen)
            {
                EncConverters.ThrowError(ErrStatus.OutputBufferFull);
            }
            rnOutLen = nLen;
            ECNormalizeData.StringToByteStar(strOutput, lpOutBuffer, rnOutLen, false);
        }