diff --git a/assets/tiled_base64_zlib.tmx b/assets/tiled_base64_zlib.tmx
index af0ae4d4d8e716db35f3c4c7e66288ea8a11df2b..b7a343d9cd3378fb3d1b9ef6f60afadd9a0389ad 100644
--- a/assets/tiled_base64_zlib.tmx
+++ b/assets/tiled_base64_zlib.tmx
@@ -2,8 +2,17 @@
 <map version="1.0" orientation="orthogonal" width="100" height="100" tilewidth="32" tileheight="32">
  <tileset firstgid="1" name="tilesheet" tilewidth="32" tileheight="32">
   <image source="tilesheet.png" width="448" height="192"/>
+  <tile id="1">
+   <properties>
+    <property name="a tile property" value="123"/>
+   </properties>
+  </tile>
  </tileset>
  <layer name="Tile Layer 1" width="100" height="100">
+  <properties>
+   <property name="prop1" value="12"/>
+   <property name="prop2" value="some text"/>
+  </properties>
   <data encoding="base64" compression="zlib">
    eJzt1zEKwzAMBVBdIScIJXPS+9+uDY1BuHbpULvLeyDIkEkfIXmLiK2qW6cYb7lqv+p41r1TcpmjZFLPyamVEXOcGSzpu66SixkZb41Xz9dO7fE+O4yR+703KmdyhExGK32v+1zv+rxLZDJO7vO5G3KvSyY1eYxT31Dlrm3t9AhZzNC6a+v3RsmhNzP83qdc8ttdHuO07thWLlt4E87w7S6wM+bo7e3ef8z1KRt5/N+388N88gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIHsArPIXTA==
   </data>
diff --git a/src/lib.rs b/src/lib.rs
index 5f77f93111ab020f24df2c290a98143f566b76ca..748bf36d70750ae60857432cc99cf0e3f0d401e3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -5,6 +5,7 @@ extern crate serialize;
 
 use std::io::{BufReader, IoError, EndOfFile};
 use std::from_str::FromStr;
+use std::collections::HashMap;
 use xml::reader::EventReader;
 use xml::common::Attribute;
 use xml::reader::events::*;
@@ -57,6 +58,24 @@ macro_rules! parse_tag {
     }
 }
 
+pub type Properties = HashMap<String, String>;
+
+fn parse_properties<B: Buffer>(parser: &mut EventReader<B>) -> Result<Properties, String> {
+    let mut p = HashMap::new();
+    parse_tag!(parser, "properties",
+               "property" => |attrs:Vec<Attribute>| {
+                    let ((), (k, v)) = get_attrs!(
+                        attrs,
+                        optionals: [],
+                        required: [("name", key, String, |v| Some(v)),
+                                   ("value", value, String, |v| Some(v))],
+                        "Property must have a name and a value".to_string());
+                    p.insert(k, v);
+                    Ok(())
+               });
+    Ok(p)
+}
+
 #[deriving(Show)]
 pub struct Map {
     version: String,
@@ -66,7 +85,8 @@ pub struct Map {
     tile_width: int,
     tile_height: int,
     tilesets: Vec<Tileset>,
-    layers: Vec<Layer>
+    layers: Vec<Layer>,
+    properties: Properties
 }
 
 impl Map {
@@ -84,6 +104,7 @@ impl Map {
 
         let mut tilesets = Vec::new();
         let mut layers = Vec::new();
+        let mut properties = HashMap::new();
         parse_tag!(parser, "map", 
                    "tileset" => |attrs| {
                         tilesets.push(try!(Tileset::new(parser, attrs)));
@@ -92,11 +113,16 @@ impl Map {
                    "layer" => |attrs| {
                         layers.push(try!(Layer::new(parser, attrs, w as uint)));
                         Ok(())
+                   },
+                   "properties" => |_| {
+                        properties = try!(parse_properties(parser));
+                        Ok(())
                    });
         Ok(Map {version: v, orientation: o,
                 width: w, height: h, 
                 tile_width: tw, tile_height: th,
-                tilesets: tilesets, layers: layers})
+                tilesets: tilesets, layers: layers,
+                properties: properties})
     }
 }
 
@@ -171,7 +197,8 @@ pub struct Layer {
     name: String,
     opacity: f32,
     visible: bool,
-    tiles: Vec<Vec<u32>>
+    tiles: Vec<Vec<u32>>,
+    properties: Properties
 }
 
 impl Layer {
@@ -183,12 +210,18 @@ impl Layer {
             required: [("name", name, String, |v| Some(v))],
             "layer must have a name".to_string());
         let mut tiles = Vec::new();
+        let mut properties = HashMap::new();
         parse_tag!(parser, "layer",
                    "data" => |attrs| {
                         tiles = try!(parse_data(parser, attrs, width));
                         Ok(())
+                   },
+                   "properties" => |_| {
+                        properties = try!(parse_properties(parser));
+                        Ok(())
                    });
-        Ok(Layer {name: n, opacity: o.unwrap_or(1.0), visible: v.unwrap_or(true), tiles: tiles })
+        Ok(Layer {name: n, opacity: o.unwrap_or(1.0), visible: v.unwrap_or(true), tiles: tiles,
+                  properties: properties})
     }
 }