Provide Group::span_open and span_close
diff --git a/src/lib.rs b/src/lib.rs
index 59de17b..2b20683 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -502,9 +502,7 @@
 /// `Delimiter`s.
 #[derive(Clone)]
 pub struct Group {
-    delimiter: Delimiter,
-    stream: TokenStream,
-    span: Span,
+    inner: imp::Group,
 }
 
 /// Describes how a sequence of token trees is delimited.
@@ -527,6 +525,18 @@
 }
 
 impl Group {
+    fn _new(inner: imp::Group) -> Self {
+        Group {
+            inner: inner,
+        }
+    }
+
+    fn _new_stable(inner: stable::Group) -> Self {
+        Group {
+            inner: inner.into(),
+        }
+    }
+
     /// Creates a new `Group` with the given delimiter and token stream.
     ///
     /// This constructor will set the span for this group to
@@ -534,15 +544,13 @@
     /// method below.
     pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
         Group {
-            delimiter: delimiter,
-            stream: stream,
-            span: Span::call_site(),
+            inner: imp::Group::new(delimiter, stream.inner),
         }
     }
 
     /// Returns the delimiter of this `Group`
     pub fn delimiter(&self) -> Delimiter {
-        self.delimiter
+        self.inner.delimiter()
     }
 
     /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
@@ -550,13 +558,40 @@
     /// Note that the returned token stream does not include the delimiter
     /// returned above.
     pub fn stream(&self) -> TokenStream {
-        self.stream.clone()
+        TokenStream::_new(self.inner.stream())
     }
 
     /// Returns the span for the delimiters of this token stream, spanning the
     /// entire `Group`.
+    ///
+    /// ```text
+    /// pub fn span(&self) -> Span {
+    ///            ^^^^^^^
+    /// ```
     pub fn span(&self) -> Span {
-        self.span
+        Span::_new(self.inner.span())
+    }
+
+    /// Returns the span pointing to the opening delimiter of this group.
+    ///
+    /// ```text
+    /// pub fn span_open(&self) -> Span {
+    ///                 ^
+    /// ```
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn span_open(&self) -> Span {
+        Span::_new(self.inner.span_open())
+    }
+
+    /// Returns the span pointing to the closing delimiter of this group.
+    ///
+    /// ```text
+    /// pub fn span_close(&self) -> Span {
+    ///                        ^
+    /// ```
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn span_close(&self) -> Span {
+        Span::_new(self.inner.span_close())
     }
 
     /// Configures the span for this `Group`'s delimiters, but not its internal
@@ -566,7 +601,7 @@
     /// by this group, but rather it will only set the span of the delimiter
     /// tokens at the level of the `Group`.
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.inner.set_span(span.inner)
     }
 }
 
@@ -574,30 +609,14 @@
 /// into the same group (modulo spans), except for possibly `TokenTree::Group`s
 /// with `Delimiter::None` delimiters.
 impl fmt::Display for Group {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let (left, right) = match self.delimiter {
-            Delimiter::Parenthesis => ("(", ")"),
-            Delimiter::Brace => ("{", "}"),
-            Delimiter::Bracket => ("[", "]"),
-            Delimiter::None => ("", ""),
-        };
-
-        f.write_str(left)?;
-        self.stream.fmt(f)?;
-        f.write_str(right)?;
-
-        Ok(())
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(&self.inner, formatter)
     }
 }
 
 impl fmt::Debug for Group {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        let mut debug = fmt.debug_struct("Group");
-        debug.field("delimiter", &self.delimiter);
-        debug.field("stream", &self.stream);
-        #[cfg(procmacro2_semver_exempt)]
-        debug.field("span", &self.span);
-        debug.finish()
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.inner, formatter)
     }
 }
 
diff --git a/src/stable.rs b/src/stable.rs
index 34df695..6c06fc4 100644
--- a/src/stable.rs
+++ b/src/stable.rs
@@ -12,7 +12,7 @@
 use strnom::{block_comment, skip_whitespace, whitespace, word_break, Cursor, PResult};
 use unicode_xid::UnicodeXID;
 
-use {Delimiter, Group, Punct, Spacing, TokenTree};
+use {Delimiter, Punct, Spacing, TokenTree};
 
 #[derive(Clone)]
 pub struct TokenStream {
@@ -432,6 +432,75 @@
 }
 
 #[derive(Clone)]
+pub struct Group {
+    delimiter: Delimiter,
+    stream: TokenStream,
+    span: Span,
+}
+
+impl Group {
+    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
+        Group {
+            delimiter: delimiter,
+            stream: stream,
+            span: Span::call_site(),
+        }
+    }
+
+    pub fn delimiter(&self) -> Delimiter {
+        self.delimiter
+    }
+
+    pub fn stream(&self) -> TokenStream {
+        self.stream.clone()
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn span_open(&self) -> Span {
+        self.span
+    }
+
+    pub fn span_close(&self) -> Span {
+        self.span
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
+    }
+}
+
+impl fmt::Display for Group {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let (left, right) = match self.delimiter {
+            Delimiter::Parenthesis => ("(", ")"),
+            Delimiter::Brace => ("{", "}"),
+            Delimiter::Bracket => ("[", "]"),
+            Delimiter::None => ("", ""),
+        };
+
+        f.write_str(left)?;
+        self.stream.fmt(f)?;
+        f.write_str(right)?;
+
+        Ok(())
+    }
+}
+
+impl fmt::Debug for Group {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        let mut debug = fmt.debug_struct("Group");
+        debug.field("delimiter", &self.delimiter);
+        debug.field("stream", &self.stream);
+        #[cfg(procmacro2_semver_exempt)]
+        debug.field("span", &self.span);
+        debug.finish()
+    }
+}
+
+#[derive(Clone)]
 pub struct Ident {
     sym: String,
     span: Span,
@@ -747,7 +816,7 @@
 }
 
 named!(token_kind -> TokenTree, alt!(
-    map!(group, TokenTree::Group)
+    map!(group, |g| TokenTree::Group(::Group::_new_stable(g)))
     |
     map!(literal, |l| TokenTree::Literal(::Literal::_new_stable(l))) // must be before symbol
     |
@@ -761,19 +830,19 @@
         punct!("("),
         token_stream,
         punct!(")")
-    ) => { |ts| Group::new(Delimiter::Parenthesis, ::TokenStream::_new_stable(ts)) }
+    ) => { |ts| Group::new(Delimiter::Parenthesis, ts) }
     |
     delimited!(
         punct!("["),
         token_stream,
         punct!("]")
-    ) => { |ts| Group::new(Delimiter::Bracket, ::TokenStream::_new_stable(ts)) }
+    ) => { |ts| Group::new(Delimiter::Bracket, ts) }
     |
     delimited!(
         punct!("{"),
         token_stream,
         punct!("}")
-    ) => { |ts| Group::new(Delimiter::Brace, ::TokenStream::_new_stable(ts)) }
+    ) => { |ts| Group::new(Delimiter::Brace, ts) }
 ));
 
 fn symbol_leading_ws(input: Cursor) -> PResult<TokenTree> {
@@ -1288,7 +1357,8 @@
     for tt in stream.iter_mut() {
         tt.set_span(span);
     }
-    trees.push(Group::new(Delimiter::Bracket, stream.into_iter().collect()).into());
+    let group = Group::new(Delimiter::Bracket, stream.into_iter().collect());
+    trees.push(::Group::_new_stable(group).into());
     for tt in trees.iter_mut() {
         tt.set_span(span);
     }
diff --git a/src/unstable.rs b/src/unstable.rs
index e8e2e2e..433639d 100644
--- a/src/unstable.rs
+++ b/src/unstable.rs
@@ -8,7 +8,7 @@
 use proc_macro;
 use stable;
 
-use {Delimiter, Group, Punct, Spacing, TokenTree};
+use {Delimiter, Punct, Spacing, TokenTree};
 
 #[derive(Clone)]
 pub enum TokenStream {
@@ -161,18 +161,7 @@
             return TokenStream::Stable(token.into());
         }
         let tt: proc_macro::TokenTree = match token {
-            TokenTree::Group(tt) => {
-                let delim = match tt.delimiter() {
-                    Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
-                    Delimiter::Bracket => proc_macro::Delimiter::Bracket,
-                    Delimiter::Brace => proc_macro::Delimiter::Brace,
-                    Delimiter::None => proc_macro::Delimiter::None,
-                };
-                let span = tt.span();
-                let mut group = proc_macro::Group::new(delim, tt.stream.inner.unwrap_nightly());
-                group.set_span(span.inner.unwrap_nightly());
-                group.into()
-            }
+            TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
             TokenTree::Punct(tt) => {
                 let spacing = match tt.spacing() {
                     Spacing::Joint => proc_macro::Spacing::Joint,
@@ -364,18 +353,7 @@
             TokenTreeIter::Stable(iter) => return iter.next(),
         };
         Some(match token {
-            proc_macro::TokenTree::Group(tt) => {
-                let delim = match tt.delimiter() {
-                    proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
-                    proc_macro::Delimiter::Bracket => Delimiter::Bracket,
-                    proc_macro::Delimiter::Brace => Delimiter::Brace,
-                    proc_macro::Delimiter::None => Delimiter::None,
-                };
-                let stream = ::TokenStream::_new(TokenStream::Nightly(tt.stream()));
-                let mut g = Group::new(delim, stream);
-                g.set_span(::Span::_new(Span::Nightly(tt.span())));
-                g.into()
-            }
+            proc_macro::TokenTree::Group(tt) => ::Group::_new(Group::Nightly(tt)).into(),
             proc_macro::TokenTree::Punct(tt) => {
                 let spacing = match tt.spacing() {
                     proc_macro::Spacing::Joint => Spacing::Joint,
@@ -594,6 +572,112 @@
 }
 
 #[derive(Clone)]
+pub enum Group {
+    Nightly(proc_macro::Group),
+    Stable(stable::Group),
+}
+
+impl Group {
+    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
+        match stream {
+            TokenStream::Nightly(stream) => {
+                let delimiter = match delimiter {
+                    Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
+                    Delimiter::Bracket => proc_macro::Delimiter::Bracket,
+                    Delimiter::Brace => proc_macro::Delimiter::Brace,
+                    Delimiter::None => proc_macro::Delimiter::None,
+                };
+                Group::Nightly(proc_macro::Group::new(delimiter, stream))
+            }
+            TokenStream::Stable(stream) => {
+                Group::Stable(stable::Group::new(delimiter, stream))
+            }
+        }
+    }
+
+    pub fn delimiter(&self) -> Delimiter {
+        match self {
+            Group::Nightly(g) => match g.delimiter() {
+                proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
+                proc_macro::Delimiter::Bracket => Delimiter::Bracket,
+                proc_macro::Delimiter::Brace => Delimiter::Brace,
+                proc_macro::Delimiter::None => Delimiter::None,
+            }
+            Group::Stable(g) => g.delimiter(),
+        }
+    }
+
+    pub fn stream(&self) -> TokenStream {
+        match self {
+            Group::Nightly(g) => TokenStream::Nightly(g.stream()),
+            Group::Stable(g) => TokenStream::Stable(g.stream()),
+        }
+    }
+
+    pub fn span(&self) -> Span {
+        match self {
+            Group::Nightly(g) => Span::Nightly(g.span()),
+            Group::Stable(g) => Span::Stable(g.span()),
+        }
+    }
+
+    #[cfg(super_unstable)]
+    pub fn span_open(&self) -> Span {
+        match self {
+            Group::Nightly(g) => Span::Nightly(g.span_open()),
+            Group::Stable(g) => Span::Stable(g.span_open()),
+        }
+    }
+
+    #[cfg(super_unstable)]
+    pub fn span_close(&self) -> Span {
+        match self {
+            Group::Nightly(g) => Span::Nightly(g.span_close()),
+            Group::Stable(g) => Span::Stable(g.span_close()),
+        }
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        match (self, span) {
+            (Group::Nightly(g), Span::Nightly(s)) => g.set_span(s),
+            (Group::Stable(g), Span::Stable(s)) => g.set_span(s),
+            _ => mismatch(),
+        }
+    }
+
+    fn unwrap_nightly(self) -> proc_macro::Group {
+        match self {
+            Group::Nightly(g) => g,
+            Group::Stable(_) => mismatch(),
+        }
+    }
+}
+
+impl From<stable::Group> for Group {
+    fn from(g: stable::Group) -> Self {
+        Group::Stable(g)
+    }
+}
+
+impl fmt::Display for Group {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            Group::Nightly(group) => group.fmt(formatter),
+            Group::Stable(group) => group.fmt(formatter),
+        }
+    }
+}
+
+impl fmt::Debug for Group {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            Group::Nightly(group) => group.fmt(formatter),
+            Group::Stable(group) => group.fmt(formatter),
+        }
+    }
+}
+
+#[derive(Clone)]
 pub enum Ident {
     Nightly(proc_macro::Ident),
     Stable(stable::Ident),