Set boundaries / limit points

Provides new `boundary` property for sets.  I could use some theoretical help on this.  I think I'm defining the set of limit points of a set.

```Python
Interval(0, 1).boundary == FiniteSet(0, 1)

FiniteSet(0, 1).boundary = FiniteSet(0, 1)

square = Interval(0, 1) ** 2
square.boundary == Interval(0, 1) * FiniteSet(0, 1) + FiniteSet(0, 1) * Interval(0, 1)

S.Reals.boundary == FiniteSet(-oo, oo)
```

Oh, fun examples:

```Python

# An L shape

In [1]: line = Interval(0, 10)

In [2]: line2 = Interval(0, 20)

In [3]: L = line2**2 - line**2

In [4]: L
Out[4]: ([0, 10] × (10, 20]) ∪ ((10, 20] × [0, 20])

In [5]: L.boundary
Out[5]: 
([0, 10] × {10, 20}) ∪ ({0, 10} × [10, 20]) ∪ 
([10, 20] × {0, 20}) ∪ ({10, 20} × [0, 20])

In [6]: L + L.boundary
Out[6]: ([0, 10] × [10, 20]) ∪ ([10, 20] × [0, 20])


# Half Circle

In [9]: r, th = symbols('r, theta', real=True)

In [10]: L = Lambda((r, th), (r*cos(th), r*sin(th)))

In [11]: halfcircle = ImageSet(L, Interval(0, 1)*Interval(0, pi))

In [12]: 

In [12]: halfcircle
Out[12]: {(r⋅cos(θ), r⋅sin(θ)) | r, θ ∊ [0, 1] × [0, π]}

In [13]: halfcircle.boundary
Out[13]: {(r⋅cos(θ), r⋅sin(θ)) | r, θ ∊ ({0, 1} × [0, π]) ∪ ([0, 1] × {0, π})}

```