fixup! Only store tokens in Attribute.
diff --git a/src/attr.rs b/src/attr.rs
index 8b5ee18..e403882 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -6,13 +6,99 @@
 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Attribute {
     pub style: AttrStyle,
-    pub value: MetaItem,
+    pub name: Ident,
+    pub tts: Vec<TokenTree>,
     pub is_sugared_doc: bool,
 }
 
 impl Attribute {
-    pub fn name(&self) -> &str {
-        self.value.name()
+    pub fn meta_item(&self) -> Option<MetaItem> {
+        if self.tts.is_empty() {
+            return Some(MetaItem::Word);
+        }
+
+        if self.tts.len() == 1 {
+            if let TokenTree::Delimited(Delimited { delim: DelimToken::Paren, ref tts }) = self.tts[0] {
+                fn nested_meta_item_from_tokens(tts: &[TokenTree]) -> Option<(NestedMetaItem, &[TokenTree])> {
+                    assert!(!tts.is_empty());
+
+                    match tts[0] {
+                        TokenTree::Token(Token::Literal(ref lit)) => {
+                            Some((NestedMetaItem::Literal(lit.clone()), &tts[1..]))
+                        }
+
+                        TokenTree::Token(Token::Ident(ref ident)) => {
+                            if tts.len() >= 3 {
+                                match (&tts[1], &tts[2]) {
+                                    (&TokenTree::Token(Token::Eq), &TokenTree::Token(Token::Literal(ref lit))) => {
+                                        return Some((NestedMetaItem::MetaItem(ident.clone(), MetaItem::NameValue(lit.clone())), &tts[3..]));
+                                    }
+
+                                    _ => {}
+                                }
+                            }
+
+                            if tts.len() >= 2 {
+                                if let TokenTree::Delimited(Delimited { delim: DelimToken::Paren, tts: ref inner_tts }) = tts[1] {
+                                    return match list_of_nested_meta_items_from_tokens(vec![], inner_tts) {
+                                        Some(nested_meta_items) => {
+                                            Some((NestedMetaItem::MetaItem(ident.clone(), MetaItem::List(nested_meta_items)), &tts[2..]))
+                                        }
+
+                                        None => None
+                                    };
+                                }
+                            }
+
+                            Some((NestedMetaItem::MetaItem(ident.clone(), MetaItem::Word), &tts[1..]))
+                        }
+
+                        _ => None
+                    }
+                }
+
+                fn list_of_nested_meta_items_from_tokens(mut result: Vec<NestedMetaItem>, tts: &[TokenTree]) -> Option<Vec<NestedMetaItem>> {
+                    if tts.is_empty() {
+                        return Some(result);
+                    }
+
+                    match nested_meta_item_from_tokens(tts) {
+                        Some((nested_meta_item, rest)) => {
+                            result.push(nested_meta_item);
+                            if rest.is_empty() {
+                                list_of_nested_meta_items_from_tokens(result, rest)
+                            }
+                            else {
+                                if let TokenTree::Token(Token::Comma) = rest[0] {
+                                    list_of_nested_meta_items_from_tokens(result, &rest[1..])
+                                }
+                                else {
+                                   None
+                                }
+                            }
+                        }
+
+                        None => None
+                    }
+                }
+
+                if let Some(nested_meta_items) = list_of_nested_meta_items_from_tokens(vec![], tts) {
+                    return Some(MetaItem::List(nested_meta_items));
+                }
+            }
+        }
+
+        if self.tts.len() == 2 {
+            match (&self.tts[0], &self.tts[1]) {
+                (&TokenTree::Token(Token::Eq), &TokenTree::Token(Token::Literal(ref lit))) => {
+                    return Some(MetaItem::NameValue(lit.clone()));
+                }
+
+                _ => {}
+            }
+        }
+
+        None
     }
 }
 
@@ -36,37 +122,17 @@
     /// Word meta item.
     ///
     /// E.g. `test` as in `#[test]`
-    Word(Ident),
+    Word,
 
     /// List meta item.
     ///
     /// E.g. `derive(..)` as in `#[derive(..)]`
-    List(Ident, Vec<NestedMetaItem>),
+    List(Vec<NestedMetaItem>),
 
     /// Name-value meta item.
     ///
     /// E.g. `feature = "foo"` as in `#[feature = "foo"]`
-    NameValue(Ident, Lit),
-
-    /// Tokens meta item.
-    ///
-    /// E.g. `test foo bar` as in `#[test foo bar]`
-    Tokens(Ident, Vec<TokenTree>),
-}
-
-impl MetaItem {
-    /// Name of the item.
-    ///
-    /// E.g. `test` as in `#[test]`, `derive` as in `#[derive(..)]`, and
-    /// `feature` as in `#[feature = "foo"]`.
-    pub fn name(&self) -> &str {
-        match *self {
-            MetaItem::Word(ref name) |
-            MetaItem::List(ref name, _) |
-            MetaItem::NameValue(ref name, _) |
-            MetaItem::Tokens(ref name, _) => name.as_ref(),
-        }
-    }
+    NameValue(Lit),
 }
 
 /// Possible values inside of compile-time attribute lists.
@@ -76,8 +142,8 @@
 pub enum NestedMetaItem {
     /// A full `MetaItem`.
     ///
-    /// E.g. `Copy` in `#[derive(Copy)]` would be a `MetaItem::Word(Ident::from("Copy"))`.
-    MetaItem(MetaItem),
+    /// E.g. `Copy` in `#[derive(Copy)]` would be a `(Ident::from("Copy"), MetaItem::Word)`.
+    MetaItem(Ident, MetaItem),
 
     /// A Rust literal.
     ///
@@ -116,7 +182,6 @@
 pub mod parsing {
     use super::*;
     use ident::parsing::ident;
-    use lit::parsing::lit;
     use mac::parsing::token_trees;
     use synom::space::{block_comment, whitespace};
 
@@ -125,13 +190,20 @@
         do_parse!(
             punct!("#") >>
             punct!("!") >>
-            punct!("[") >>
-            meta_item: meta_item >>
-            punct!("]") >>
-            (Attribute {
-                style: AttrStyle::Inner,
-                value: meta_item,
-                is_sugared_doc: false,
+            name_and_tts: delimited!(
+                punct!("["),
+                tuple!(ident, token_trees),
+                punct!("]")
+            ) >>
+            ({
+                let (name, tts) = name_and_tts;
+
+                Attribute {
+                    style: AttrStyle::Inner,
+                    name: name,
+                    tts: tts,
+                    is_sugared_doc: false,
+                }
             })
         )
         |
@@ -140,10 +212,11 @@
             content: take_until!("\n") >>
             (Attribute {
                 style: AttrStyle::Inner,
-                value: MetaItem::NameValue(
-                    "doc".into(),
-                    format!("//!{}", content).into(),
-                ),
+                name: "doc".into(),
+                tts: vec![
+                    TokenTree::Token(Token::Eq),
+                    TokenTree::Token(Token::Literal(Lit::Str(format!("//!{}", content).into(), StrStyle::Cooked))),
+                ],
                 is_sugared_doc: true,
             })
         )
@@ -154,10 +227,11 @@
             com: block_comment >>
             (Attribute {
                 style: AttrStyle::Inner,
-                value: MetaItem::NameValue(
-                    "doc".into(),
-                    com.into(),
-                ),
+                name: "doc".into(),
+                tts: vec![
+                    TokenTree::Token(Token::Eq),
+                    TokenTree::Token(Token::Literal(Lit::Str(com.into(), StrStyle::Cooked))),
+                ],
                 is_sugared_doc: true,
             })
         )
@@ -166,32 +240,20 @@
     named!(pub outer_attr -> Attribute, alt!(
         do_parse!(
             punct!("#") >>
-            punct!("[") >>
-            meta_item: meta_item >>
-            punct!("]") >>
-            (Attribute {
-                style: AttrStyle::Outer,
-                value: meta_item,
-                is_sugared_doc: false,
-            })
-        )
-        |
-        do_parse!(
-            name_and_token_trees: preceded!(
-                punct!("#"),
-                delimited!(
-                    punct!("["),
-                    tuple!(ident, token_trees),
-                    punct!("]")
-                )
+            name_and_tts: delimited!(
+                punct!("["),
+                tuple!(ident, token_trees),
+                punct!("]")
             ) >>
-            (Attribute {
-                style: AttrStyle::Outer,
-                value: {
-                    let (name, token_trees) = name_and_token_trees;
-                    MetaItem::Tokens(name, token_trees)
-                },
-                is_sugared_doc: false,
+            ({
+                let (name, tts) = name_and_tts;
+
+                Attribute {
+                    style: AttrStyle::Outer,
+                    name: name,
+                    tts: tts,
+                    is_sugared_doc: false,
+                }
             })
         )
         |
@@ -201,10 +263,11 @@
             content: take_until!("\n") >>
             (Attribute {
                 style: AttrStyle::Outer,
-                value: MetaItem::NameValue(
-                    "doc".into(),
-                    format!("///{}", content).into(),
-                ),
+                name: "doc".into(),
+                tts: vec![
+                    TokenTree::Token(Token::Eq),
+                    TokenTree::Token(Token::Literal(Lit::Str(format!("///{}", content).into(), StrStyle::Cooked))),
+                ],
                 is_sugared_doc: true,
             })
         )
@@ -215,39 +278,15 @@
             com: block_comment >>
             (Attribute {
                 style: AttrStyle::Outer,
-                value: MetaItem::NameValue(
-                    "doc".into(),
-                    com.into(),
-                ),
+                name: "doc".into(),
+                tts: vec![
+                    TokenTree::Token(Token::Eq),
+                    TokenTree::Token(Token::Literal(Lit::Str(com.into(), StrStyle::Cooked))),
+                ],
                 is_sugared_doc: true,
             })
         )
     ));
-
-    named!(meta_item -> MetaItem, alt!(
-        do_parse!(
-            id: ident >>
-            punct!("(") >>
-            inner: terminated_list!(punct!(","), nested_meta_item) >>
-            punct!(")") >>
-            (MetaItem::List(id, inner))
-        )
-        |
-        do_parse!(
-            name: ident >>
-            punct!("=") >>
-            value: lit >>
-            (MetaItem::NameValue(name, value))
-        )
-        |
-        map!(ident, MetaItem::Word)
-    ));
-
-    named!(nested_meta_item -> NestedMetaItem, alt!(
-        meta_item => { NestedMetaItem::MetaItem }
-        |
-        lit => { NestedMetaItem::Literal }
-    ));
 }
 
 #[cfg(feature = "printing")]
@@ -258,28 +297,32 @@
 
     impl ToTokens for Attribute {
         fn to_tokens(&self, tokens: &mut Tokens) {
-            if let Attribute { style,
-                               value: MetaItem::NameValue(ref name,
-                                                   Lit::Str(ref value, StrStyle::Cooked)),
-                               is_sugared_doc: true } = *self {
-                if name == "doc" {
-                    match style {
-                        AttrStyle::Inner if value.starts_with("//!") => {
-                            tokens.append(&format!("{}\n", value));
-                            return;
+            if let Attribute { style, ref name, ref tts, is_sugared_doc: true } = *self {
+                if name == "doc" && tts.len() == 2 {
+                    match (&tts[0], &tts[1]) {
+                        (&TokenTree::Token(Token::Eq),
+                         &TokenTree::Token(Token::Literal(Lit::Str(ref value, StrStyle::Cooked)))) => {
+                            match style {
+                                AttrStyle::Inner if value.starts_with("//!") => {
+                                    tokens.append(&format!("{}\n", value));
+                                    return;
+                                }
+                                AttrStyle::Inner if value.starts_with("/*!") => {
+                                    tokens.append(value);
+                                    return;
+                                }
+                                AttrStyle::Outer if value.starts_with("///") => {
+                                    tokens.append(&format!("{}\n", value));
+                                    return;
+                                }
+                                AttrStyle::Outer if value.starts_with("/**") => {
+                                    tokens.append(value);
+                                    return;
+                                }
+                                _ => {}
+                            }
                         }
-                        AttrStyle::Inner if value.starts_with("/*!") => {
-                            tokens.append(value);
-                            return;
-                        }
-                        AttrStyle::Outer if value.starts_with("///") => {
-                            tokens.append(&format!("{}\n", value));
-                            return;
-                        }
-                        AttrStyle::Outer if value.starts_with("/**") => {
-                            tokens.append(value);
-                            return;
-                        }
+
                         _ => {}
                     }
                 }
@@ -290,7 +333,8 @@
                 tokens.append("!");
             }
             tokens.append("[");
-            self.value.to_tokens(tokens);
+            self.name.to_tokens(tokens);
+            tokens.append_all(&self.tts);
             tokens.append("]");
         }
     }
@@ -298,24 +342,16 @@
     impl ToTokens for MetaItem {
         fn to_tokens(&self, tokens: &mut Tokens) {
             match *self {
-                MetaItem::Word(ref ident) => {
-                    ident.to_tokens(tokens);
-                }
-                MetaItem::List(ref ident, ref inner) => {
-                    ident.to_tokens(tokens);
+                MetaItem::Word => {}
+                MetaItem::List(ref inner) => {
                     tokens.append("(");
                     tokens.append_separated(inner, ",");
                     tokens.append(")");
                 }
-                MetaItem::NameValue(ref name, ref value) => {
-                    name.to_tokens(tokens);
+                MetaItem::NameValue(ref value) => {
                     tokens.append("=");
                     value.to_tokens(tokens);
                 }
-                MetaItem::Tokens(ref name, ref token_trees) => {
-                    name.to_tokens(tokens);
-                    tokens.append_all(token_trees);
-                }
             }
         }
     }
@@ -323,7 +359,8 @@
     impl ToTokens for NestedMetaItem {
         fn to_tokens(&self, tokens: &mut Tokens) {
             match *self {
-                NestedMetaItem::MetaItem(ref nested) => {
+                NestedMetaItem::MetaItem(ref ident, ref nested) => {
+                    ident.to_tokens(tokens);
                     nested.to_tokens(tokens);
                 }
                 NestedMetaItem::Literal(ref lit) => {