/// <summary> /// Obtains a mode from a list of atomic (already sorted) modes. /// Used by fall back generation. /// </summary> public IKeyboardMode ObtainMode( IKeyboardMode[] atomicModes, int count ) { Debug.Assert( count > 1, "Atomic modes are handled directly." ); Debug.Assert( !Array.Exists( atomicModes, delegate( IKeyboardMode mA ) { return mA.Context != this || mA.AtomicModes.Count != 1; } ), "Modes are from this Context and they are atomic and not empty." ); StringBuilder b = new StringBuilder( atomicModes[0].ToString() ); for ( int i = 1; i < count; ++i ) { Debug.Assert( StringComparer.Ordinal.Compare( atomicModes[i - 1].ToString(), atomicModes[i].ToString() ) < 0, "Modes are already sorted and NO DUPLICATE exists." ); b.Append( '+' ).Append( atomicModes[i].ToString() ); } string modes = b.ToString(); KeyboardMode m; if ( !_modes.TryGetValue( modes, out m ) ) { if ( atomicModes.Length != count ) { IKeyboardMode[] subArray = new IKeyboardMode[count]; Array.Copy( atomicModes, subArray, count ); atomicModes = subArray; } else atomicModes = (IKeyboardMode[])atomicModes.Clone(); m = new KeyboardMode( this, modes, new CKReadOnlyListOnIList<IKeyboardMode>( atomicModes ) ); _modes.Add( modes, m ); } return m; }