<commit_before>using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Windows.Input;
using PicoMVVM.ViewModels;

namespace PicoMVVM.Commands
{
	/// <summary>
	/// A command whose sole purpose is to relay its functionality to other
	/// objects by invoking delegates. CanExecute and CanExecuteChanged are bound to 
	/// a property of another object.
	/// </summary>
	public class BoundRelayCommand<TSource> 
		: ICommand where TSource : INotifyPropertyChanged
	{
		/// <summary>
		/// Creates a new command.
		/// </summary>
		/// <param name="execute">The execution logic.</param>
		/// <param name="canExecuteProperty">An expression referencing a boolean property that determines the command's execution status</param>
		/// <param name="propertyDeclarer">The object that declares the property that triggers a change in command execution status</param>
		public BoundRelayCommand(Action<object> execute, Expression<Func<TSource, bool>> canExecuteProperty, TSource propertyDeclarer)
		{
			if (execute == null)
				throw new ArgumentNullException("execute");

			if (canExecuteProperty == null)
				throw new ArgumentNullException("canExecuteProperty");

			if (propertyDeclarer == null)
				throw new ArgumentNullException("propertyDeclarer");

			_execute = execute;

			var property = Reflect.PropertyOf(canExecuteProperty);
			_propertyName = property.Name;
			propertyDeclarer.PropertyChanged += propertyDeclarer_PropertyChanged;
			Func<TSource, bool> func = canExecuteProperty.Compile();
			_canExecute = () => func(propertyDeclarer);
		}

		#region ICommand Members

		/// <see cref="ICommand.CanExecute"/>
		[DebuggerStepThrough]
		public bool CanExecute(object parameter)
		{
			return _canExecute();
		}

		/// <see cref="ICommand.Execute"/>
		public void Execute(object parameter)
		{
			_execute(parameter);
		}

		/// <see cref="ICommand.CanExecuteChanged"/>
		public event EventHandler CanExecuteChanged;

		private void OnCanExecuteChanged()
		{
			var localEvent = CanExecuteChanged;
			if (localEvent != null)
				localEvent(this, EventArgs.Empty);
		}

		#endregion

		void propertyDeclarer_PropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			if (e.PropertyName == _propertyName)
				OnCanExecuteChanged();
		}

		private readonly Action<object> _execute;
		private readonly Func<bool> _canExecute;
		private readonly string _propertyName;
	}
}<commit_msg>Added new ability to bind to nullable property<commit_after>using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Windows.Input;
using PicoMVVM.ViewModels;

namespace PicoMVVM.Commands
{
	/// <summary>
	/// A command whose sole purpose is to relay its functionality to other
	/// objects by invoking delegates. CanExecute and CanExecuteChanged are bound to 
	/// a property of another object.
	/// </summary>
	public class BoundRelayCommand<TSource> 
		: ICommand where TSource : INotifyPropertyChanged
	{
		/// <summary>
		/// Creates a new command. Bound can execute to a nullable property
		/// </summary>
		/// <param name="execute">The execution logic.</param>
		/// <param name="isNullProperty">An expression referencing a object that if null will be false</param>
		/// <param name="propertyDeclarer">The object that declares the property that triggers a change in command execution status</param>
		public BoundRelayCommand(Action<object> execute, Expression<Func<TSource, object>> isNullProperty, TSource propertyDeclarer)
		{
			if (execute == null)
				throw new ArgumentNullException("execute");

			if (isNullProperty == null)
				throw new ArgumentNullException("isNullProperty");

			if (propertyDeclarer == null)
				throw new ArgumentNullException("propertyDeclarer");

			_execute = execute;

			var property = Reflect.PropertyOf(isNullProperty);
			_propertyName = property.Name;
			propertyDeclarer.PropertyChanged += propertyDeclarer_PropertyChanged;
			var prop = isNullProperty.Compile();
			Func<TSource, bool> func = src => prop.Invoke(src) != null;
			_canExecute = () => func(propertyDeclarer);
		}

		/// <summary>
		/// Creates a new command. Bound can execute to a boolean property
		/// </summary>
		/// <param name="execute">The execution logic.</param>
		/// <param name="canExecuteProperty">An expression referencing a boolean property that determines the command's execution status</param>
		/// <param name="propertyDeclarer">The object that declares the property that triggers a change in command execution status</param>
		public BoundRelayCommand(Action<object> execute, Expression<Func<TSource, bool>> canExecuteProperty, TSource propertyDeclarer)
		{
			if (execute == null)
				throw new ArgumentNullException("execute");

			if (canExecuteProperty == null)
				throw new ArgumentNullException("canExecuteProperty");

			if (propertyDeclarer == null)
				throw new ArgumentNullException("propertyDeclarer");

			_execute = execute;

			var property = Reflect.PropertyOf(canExecuteProperty);
			_propertyName = property.Name;
			propertyDeclarer.PropertyChanged += propertyDeclarer_PropertyChanged;
			Func<TSource, bool> func = canExecuteProperty.Compile();
			_canExecute = () => func(propertyDeclarer);
		}

		#region ICommand Members

		/// <see cref="ICommand.CanExecute"/>
		[DebuggerStepThrough]
		public bool CanExecute(object parameter)
		{
			return _canExecute();
		}

		/// <see cref="ICommand.Execute"/>
		public void Execute(object parameter)
		{
			_execute(parameter);
		}

		/// <see cref="ICommand.CanExecuteChanged"/>
		public event EventHandler CanExecuteChanged;

		private void OnCanExecuteChanged()
		{
			var localEvent = CanExecuteChanged;
			if (localEvent != null)
				localEvent(this, EventArgs.Empty);
		}

		#endregion

		void propertyDeclarer_PropertyChanged(object sender, PropertyChangedEventArgs e)
		{
			if (e.PropertyName == _propertyName)
				OnCanExecuteChanged();
		}

		private readonly Action<object> _execute;
		private readonly Func<bool> _canExecute;
		private readonly string _propertyName;
	}
}
{'fraction_non_alphanumeric': 0.10348226018396846, 'fraction_numerical': 0.0, 'mean_word_length': 4.4317573595004465, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1875684', 'n_tokens_mistral': 1889, 'n_tokens_neox': 1632, 'n_words': 478}