Helper function split_impl_generics
diff --git a/src/generics.rs b/src/generics.rs
index bc96319..851a209 100644
--- a/src/generics.rs
+++ b/src/generics.rs
@@ -9,6 +9,61 @@
     pub where_clause: WhereClause,
 }
 
+impl Generics {
+    /// Split a type's generics into the pieces required for impl'ing a trait
+    /// for that type.
+    ///
+    /// ```
+    /// # extern crate syn;
+    /// # #[macro_use]
+    /// # extern crate quote;
+    /// # fn main() {
+    /// # let generics: syn::Generics = Default::default();
+    /// # let name = syn::Ident::new("MyType");
+    /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+    /// quote! {
+    ///     impl #impl_generics MyTrait for #name #ty_generics #where_clause {
+    ///         // ...
+    ///     }
+    /// }
+    /// # ;
+    /// # }
+    /// ```
+    pub fn split_for_impl(&self) -> (Generics, Generics, WhereClause) {
+        // Remove where clause and type parameter defaults.
+        let impl_generics = Generics {
+            lifetimes: self.lifetimes.clone(),
+            ty_params: self.ty_params.iter().map(|ty_param| {
+                TyParam {
+                    ident: ty_param.ident.clone(),
+                    bounds: ty_param.bounds.clone(),
+                    default: None,
+                }}).collect(),
+            where_clause: WhereClause::none(),
+        };
+
+        // Remove where clause, type parameter defaults, and bounds.
+        let ty_generics = Generics {
+            lifetimes: self.lifetimes.iter().map(|lifetime_def| {
+                LifetimeDef {
+                    lifetime: lifetime_def.lifetime.clone(),
+                    bounds: Vec::new(),
+                }}).collect(),
+            ty_params: self.ty_params.iter().map(|ty_param| {
+                TyParam {
+                    ident: ty_param.ident.clone(),
+                    bounds: Vec::new(),
+                    default: None,
+                }}).collect(),
+            where_clause: WhereClause::none(),
+        };
+
+        let where_clause = self.where_clause.clone();
+
+        (impl_generics, ty_generics, where_clause)
+    }
+}
+
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Lifetime {
     pub ident: Ident,
@@ -69,6 +124,14 @@
     pub predicates: Vec<WherePredicate>,
 }
 
+impl WhereClause {
+    pub fn none() -> Self {
+        WhereClause {
+            predicates: Vec::new(),
+        }
+    }
+}
+
 /// A single predicate in a `where` clause
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum WherePredicate {
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
new file mode 100644
index 0000000..c28f044
--- /dev/null
+++ b/tests/test_generics.rs
@@ -0,0 +1,113 @@
+extern crate syn;
+use syn::*;
+
+fn simple_path(name: &'static str) -> Path {
+    Path {
+        global: false,
+        segments: vec![
+            PathSegment {
+                ident: Ident::new(name),
+                parameters: PathParameters::none(),
+            },
+        ],
+    }
+}
+
+#[test]
+fn test_split_for_impl() {
+    // <'a, 'b: 'a, T: 'a = ()> where T: Debug
+    let generics = Generics {
+        lifetimes: vec![
+            LifetimeDef {
+                lifetime: Lifetime::new("'a"),
+                bounds: Vec::new(),
+            },
+            LifetimeDef {
+                lifetime: Lifetime::new("'b"),
+                bounds: vec![
+                    Lifetime::new("'a"),
+                ],
+            },
+        ],
+        ty_params: vec![
+            TyParam {
+                ident: Ident::new("T"),
+                bounds: vec![
+                    TyParamBound::Region(Lifetime::new("'a")),
+                ],
+                default: Some(Ty::Tup(Vec::new())),
+            },
+        ],
+        where_clause: WhereClause {
+            predicates: vec![
+                WherePredicate::BoundPredicate(WhereBoundPredicate {
+                    bound_lifetimes: Vec::new(),
+                    bounded_ty: Ty::Path(None, simple_path("T")),
+                    bounds: vec![
+                        TyParamBound::Trait(
+                            PolyTraitRef {
+                                bound_lifetimes: Vec::new(),
+                                trait_ref: simple_path("Debug"),
+                            },
+                            TraitBoundModifier::None,
+                        ),
+                    ],
+                }),
+            ],
+        },
+    };
+
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+    // <'a, 'b: 'a, T: 'a>
+    let expected_impl_generics = Generics {
+        lifetimes: vec![
+            LifetimeDef {
+                lifetime: Lifetime::new("'a"),
+                bounds: Vec::new(),
+            },
+            LifetimeDef {
+                lifetime: Lifetime::new("'b"),
+                bounds: vec![
+                    Lifetime::new("'a"),
+                ],
+            },
+        ],
+        ty_params: vec![
+            TyParam {
+                ident: Ident::new("T"),
+                bounds: vec![
+                    TyParamBound::Region(Lifetime::new("'a")),
+                ],
+                default: None,
+            },
+        ],
+        where_clause: WhereClause::none(),
+    };
+
+    // <'a, 'b, T>
+    let expected_ty_generics = Generics {
+        lifetimes: vec![
+            LifetimeDef {
+                lifetime: Lifetime::new("'a"),
+                bounds: Vec::new(),
+            },
+            LifetimeDef {
+                lifetime: Lifetime::new("'b"),
+                bounds: Vec::new(),
+            },
+        ],
+        ty_params: vec![
+            TyParam {
+                ident: Ident::new("T"),
+                bounds: Vec::new(),
+                default: None,
+            },
+        ],
+        where_clause: WhereClause::none(),
+    };
+
+    assert_eq!(impl_generics, expected_impl_generics);
+    assert_eq!(ty_generics, expected_ty_generics);
+    assert_eq!(where_clause, generics.where_clause);
+}