private unsafe LsErr AdjustChars(
            LsCharRunInfo       *plscharrunInfo,
            bool                expanding,
            int                 interWordAdjustTo,
            int**               pplsAdjustLeft,
            int**               pplsAdjustRight
            )
        {
            char* pwch = plscharrunInfo->pwch;
            int cchRun = plscharrunInfo->cwch;


            for (int i = 0; i < cchRun; i++)
            {
                int adjustedCharWidth = plscharrunInfo->rgduNominalWidth[i] + plscharrunInfo->rgduChangeLeft[i] + plscharrunInfo->rgduChangeRight[i];


                pplsAdjustLeft[0][i] = 0;
                pplsAdjustLeft[1][i] = 0;
                pplsAdjustLeft[2][i] = 0;


                pplsAdjustRight[0][i] = 0;
                pplsAdjustRight[1][i] = 0;
                pplsAdjustRight[2][i] = 0;

                ushort flags = (ushort)(Classification.CharAttributeOf((int)Classification.GetUnicodeClassUTF16(pwch[i]))).Flags;
                if ((flags & ((ushort)CharacterAttributeFlags.CharacterSpace)) != 0)
                {
                    if (expanding)
                    {
                        int expandedBy = Math.Max(0, interWordAdjustTo - adjustedCharWidth);
                        pplsAdjustRight[0][i] = expandedBy;
                        pplsAdjustRight[1][i] = expandedBy * Constants.AcceptableLineStretchability;
                        pplsAdjustRight[2][i] = FullText.FormatWidth;
                    }
                    else
                    {
                        pplsAdjustRight[0][i] = Math.Max(0, adjustedCharWidth - interWordAdjustTo);
                    }
                }
                else if (expanding)
                {

                    pplsAdjustRight[2][i] = FullText.FormatWidth; 
                }
            }
            return LsErr.None;
        }
        internal unsafe LsErr GetCharExpansionInfoFullMixed(
            IntPtr              pols,                   // Line Layout context
            LsDevice            device,                 // kind of device
            LsTFlow             textFlow,               // text flow
            LsCharRunInfo       *plscharrunInfo,        // char-based run info
            LsNeighborInfo      *plsneighborInfoLeft,   // left neighbor info
            LsNeighborInfo      *plsneighborInfoRight,  // right neigbor info
            int                 maxPriorityLevel,       // maximum priority level
            int**               pplsexpansionLeft,      // [in/out] fill in left expansion amount per priority level on the way out
            int**               pplsexpansionRight      // [in/out] fill in right expansion amount per priority level on the way out
            )
        {
            LsErr lserr = LsErr.None;
            Plsrun plsrun = Plsrun.Undefined;
            LSRun lsrun = null;

            try
            {
                Invariant.Assert(maxPriorityLevel == 3);

                plsrun = plscharrunInfo->plsrun;
                lsrun = FullText.StoreFrom(plsrun).GetRun(plsrun);

                return AdjustChars(
                    plscharrunInfo,
                    true,   // expanding
                    (int)(lsrun.EmSize * Constants.MaxInterWordExpansionPerEm),
                    pplsexpansionLeft,
                    pplsexpansionRight
                    );
            }
            catch (Exception e)
            {
                SaveException(e, plsrun, lsrun);
                lserr = LsErr.ClientAbort;
            }
            catch
            {
                SaveNonCLSException("GetCharExpansionInfoFullMixed", plsrun, lsrun);
                lserr = LsErr.ClientAbort;
            }
            return lserr;
        }