Too Many Staff Meetings I recently got in really deep on a question to find the overlapping meetings and I rewrote a bit of the code and added some things to the code, and I would just like a general review of my code and what I could do to make it even better, maybe performance wise or whatever.

Here is my LINQPad 5 Code Dump, you should be able to copy paste into LINQPad and run it, I don't think I did anything that is too cutting edge.

{
    var format = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;
    Meeting[] meetings = new Meeting[]
    {
        new Meeting(DateTime.Parse("1/1/2015 21:30", format), DateTime.Parse("1/1/2015 23:00", format)),
        new Meeting(DateTime.Parse("1/1/2015 23:10", format), DateTime.Parse("1/1/2015 23:30", format)),
        new Meeting(DateTime.Parse("1/1/2015 20:00", format), DateTime.Parse("1/1/2015 21:30", format)),
        new Meeting(DateTime.Parse("1/1/2015 22:10", format), DateTime.Parse("1/1/2015 22:20", format)),
        new Meeting(DateTime.Parse("1/1/2015 23:20", format), DateTime.Parse("1/1/2015 23:50", format)),
        new Meeting(DateTime.Parse("1/1/2015 23:20", format), DateTime.Parse("1/2/2015 00:00", format)),
        new Meeting(DateTime.Parse("1/2/2015 09:00", format), DateTime.Parse("1/2/2015 12:00", format)),
        new Meeting(DateTime.Parse("1/2/2015 09:00", format), DateTime.Parse("1/2/2015 10:00", format)),
        new Meeting(DateTime.Parse("1/2/2015 11:00", format), DateTime.Parse("1/2/2015 11:30", format))
    };

    var overlappingMeetings = meetings.Overlappings();
    var meetingsOverlap = meetings.Overlappings().Any();
    overlappingMeetings.Dump();
    meetingsOverlap.Dump();
}

public static class StaffMeetings
{
    public static IEnumerable&lt;Meeting[]&gt; Overlappings(this IEnumerable&lt;Meeting&gt; meetings)
    {
        var first = (Meeting)null;
        var orderedMeetings = meetings.OrderBy(m =&gt; m.Start);
        var checkedMeetings = new List&lt;Meeting&gt;();

        foreach (var meeting in orderedMeetings)
        {
            if (first != null)
            {
                checkedMeetings.Add(first);
                var uncheckedMeetings = orderedMeetings.Where(x =&gt; (x.Start &gt;= first.Start &amp;&amp; !(x == first)) &amp;&amp; !checkedMeetings.Any(m =&gt; m == x));
                foreach (var meet in uncheckedMeetings)
                {
                    if (first.OverlapsWith(meet))
                    {
                        yield return new[] { first, meet };
                    }
                }
            }
            first = meeting;
        }
    }
}
public class Meeting
{
    public DateTime Start { get; private set; }
    public DateTime End { get; private set; }

    public Meeting(DateTime start, DateTime end)
    {
        if (end &lt; start)
        {
            throw new ArgumentException("Cannot create a meeting that ends before it starts.");
        }
        this.Start = start;
        this.End = end;
    }

    public bool OverlapsWith(Meeting second)
    {
        return this.End &gt; second.Start;
    }
    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }
    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}


here are the results of that run as well



Did I miss anything?

Are there more edge cases that I didn't consider?

Is there a nice, neat, acceptable way of streamlining the foreach statements with the if statements inside of them?  (Kind of curious if it is possible to one line it)
Just a quick shot
This

public override bool Equals(object obj)
{
    return base.Equals(obj);
}
public override int GetHashCode()
{
    return base.GetHashCode();
}  


doesn't buy you anything. Overriding a method and the calling the base method is just rubbish which lays around in the codebase.