private static OperationalEnumerable<short, int> AsOperationalInternal(
      IEnumerable<short> source,
      Func<IEnumerable<short>, IEnumerable<short>, Func<short, short, int>, IEnumerable<int>> binaryOperation = null,
      Func<IEnumerable<int>, IEnumerable<int>, Func<int, int, int>, IEnumerable<int>> resultBinaryOperation = null,
      Func<IEnumerable<short>, IEnumerable<int>, Func<short, int, int>, IEnumerable<int>> shiftOperation = null,
      Func<IEnumerable<short>, IEnumerable<short>, Func<short, short, bool>, IEnumerable<bool>> comparisonOperation = null,
      IComparer<short> comparer = null,
      IEqualityComparer<short> equalityComparer = null)
    {
      Contract.Requires(source != null);
      Contract.Ensures(!object.Equals(Contract.Result<OperationalEnumerable<short, int>>(), null));

      return source.AsOperational(
        result => AsOperationalInternal(result, resultBinaryOperation),
        binaryOperation: binaryOperation,
        comparisonOperation: comparisonOperation,
        shiftOperation: shiftOperation,
        add: (first, second) => first + second,
        subtract: (first, second) => first - second,
        multiply: (first, second) => first * second,
        divide: (first, second) => first / second,
        remainder: (first, second) => first % second,
        leftShift: (first, second) => first << second,
        rightShift: (first, second) => first >> second,
        positive: value => +value,
        negative: value => -value,
        complement: value => ~value,
        not: null,
        equals: (first, second) => equalityComparer == null ? first == second : equalityComparer.Equals(first, second),
        notEquals: (first, second) => equalityComparer == null ? first != second : !equalityComparer.Equals(first, second),
        lessThan: (first, second) => comparer == null ? first < second : comparer.Compare(first, second) < 0,
        lessThanOrEqual: (first, second) => comparer == null ? first <= second : comparer.Compare(first, second) <= 0,
        greaterThan: (first, second) => comparer == null ? first > second : comparer.Compare(first, second) > 0,
        greaterThanOrEqual: (first, second) => comparer == null ? first >= second : comparer.Compare(first, second) >= 0,
        and: (first, second) => first & second,
        or: (first, second) => first | second,
        xor: (first, second) => first ^ second);
    }
    private static OperationalEnumerable<string> AsOperationalInternal(
      IEnumerable<string> source,
      Func<IEnumerable<string>, IEnumerable<string>, Func<string, string, string>, IEnumerable<string>> binaryOperation = null,
      Func<IEnumerable<string>, IEnumerable<string>, Func<string, string, bool>, IEnumerable<bool>> comparisonOperation = null,
      IComparer<string> comparer = null,
      IEqualityComparer<string> equalityComparer = null)
    {
      Contract.Requires(source != null);
      Contract.Ensures(!object.Equals(Contract.Result<OperationalEnumerable<string>>(), null));

      return source.AsOperational(
        binaryOperation: binaryOperation,
        comparisonOperation: comparisonOperation,
        add: (first, second) => first + second,
        subtract: null,
        multiply: null,
        divide: null,
        remainder: null,
        leftShift: null,
        rightShift: null,
        positive: null,
        negative: null,
        complement: null,
        not: null,
        equals: (first, second) => equalityComparer == null ? first == second : equalityComparer.Equals(first, second),
        notEquals: (first, second) => equalityComparer == null ? first != second : !equalityComparer.Equals(first, second),
        lessThan: (first, second) => (comparer ?? StringComparer.Ordinal).Compare(first, second) < 0,
        lessThanOrEqual: (first, second) => (comparer ?? StringComparer.Ordinal).Compare(first, second) <= 0,
        greaterThan: (first, second) => (comparer ?? StringComparer.Ordinal).Compare(first, second) > 0,
        greaterThanOrEqual: (first, second) => (comparer ?? StringComparer.Ordinal).Compare(first, second) >= 0,
        and: null,
        or: null,
        xor: null);
    }