public static DynamicMetaObject/*!*/ Operation(UnaryOperationBinder/*!*/ operation, DynamicMetaObject arg, DynamicMetaObject errorSuggestion) {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback UnaryOperator " + " " + operation.Operation + " " + arg.LimitType.FullName);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString());

            DynamicMetaObject[] args = new[] { arg };
            if (arg.NeedsDeferral()) {
                return operation.Defer(arg);
            }

            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args);

            DynamicMetaObject res = null;
            Type retType = typeof(object);
            switch (operation.Operation) {
                case ExpressionType.UnaryPlus:
                    res = BindingHelpers.AddPythonBoxing(MakeUnaryOperation(operation, arg, "__pos__", errorSuggestion));
                    break;
                case ExpressionType.Negate:
                    res = BindingHelpers.AddPythonBoxing(MakeUnaryOperation(operation, arg, "__neg__", errorSuggestion));
                    break;
                case ExpressionType.OnesComplement:
                    res = BindingHelpers.AddPythonBoxing(MakeUnaryOperation(operation, arg, "__invert__", errorSuggestion));
                    break;
                case ExpressionType.Not:
                    res = MakeUnaryNotOperation(operation, arg, typeof(object), errorSuggestion);
                    break;
                case ExpressionType.IsFalse:
                    res = MakeUnaryNotOperation(operation, arg, typeof(bool), errorSuggestion);
                    retType = typeof(bool);
                    break;
                case ExpressionType.IsTrue:
                    res = PythonProtocol.ConvertToBool(operation, arg);
                    retType = typeof(bool);
                    break;
                default:
                    res = TypeError(operation, "unknown operation: " + operation.ToString(), args);
                    break;

            }

            return BindingHelpers.AddDynamicTestAndDefer(operation, res, args, valInfo, retType);
        }
        public static DynamicMetaObject Operation(UnaryOperationBinder operation, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
        {
            PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Fallback UnaryOperator " + " " + operation.Operation + " " + arg.LimitType.FullName);
            PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, operation.Operation.ToString());

            DynamicMetaObject[] args = new[] { arg };
            if (arg.NeedsDeferral())
                return operation.Defer(arg);

            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(args);

            TotemOperationKind? toOperator = null;
            Type retType = typeof(object);
            bool box = true;
            bool inverse = false;
            switch (operation.Operation)
            {
                case ExpressionType.UnaryPlus: toOperator = TotemOperationKind.Positive; break;
                case ExpressionType.Negate: toOperator = TotemOperationKind.Negate; break;
                case ExpressionType.OnesComplement: toOperator = TotemOperationKind.OnesComplement; break;
                case ExpressionType.Not: toOperator = TotemOperationKind.Not; box = false; break;
                case ExpressionType.IsFalse: toOperator = TotemOperationKind.IsFalse; box = false; retType = typeof(bool); break;
                case ExpressionType.IsTrue: toOperator = TotemOperationKind.IsFalse; box = false; retType = typeof(bool); inverse = true; break;
            }

            DynamicMetaObject res = null;
            if (toOperator != null)
                res = MakeUnaryOperation(operation, args[0], toOperator.Value, errorSuggestion, retType);
            else
                res = operation.FallbackUnaryOperation(arg);

            if (inverse)
            {
                res = new DynamicMetaObject(
                    Expression.Condition(
                        res.Expression,
                        Utils.Constant(ScriptingRuntimeHelpers.False),
                        Utils.Constant(ScriptingRuntimeHelpers.True)
                    ),
                    res.Restrictions
                );
            }

            if (box)
            {
                res = BindingHelpers.AddTotemBoxing(res);
            }

            return BindingHelpers.AddDynamicTestAndDefer(operation, res, args, valInfo, retType);
        }