diff -pruN 2.2.0-3/Cargo.toml 2.4.0-1/Cargo.toml
--- 2.2.0-3/Cargo.toml	1970-01-01 00:00:00.000000000 +0000
+++ 2.4.0-1/Cargo.toml	1970-01-01 00:00:01.000000000 +0000
@@ -3,7 +3,7 @@
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
+# to registry (e.g., crates.io) dependencies
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
@@ -12,7 +12,7 @@
 
 [package]
 name = "xdg"
-version = "2.2.0"
+version = "2.4.0"
 authors = ["Ben Longbons <b.r.longbons@gmail.com>", "whitequark <whitequark@whitequark.org>"]
 description = "A library for storing and retrieving files according to XDG Base Directory specification"
 homepage = "https://github.com/whitequark/rust-xdg"
@@ -24,3 +24,5 @@ repository = "https://github.com/whitequ
 
 [lib]
 doctest = false
+[dependencies.dirs]
+version = "3.0"
diff -pruN 2.2.0-3/Cargo.toml.orig 2.4.0-1/Cargo.toml.orig
--- 2.2.0-3/Cargo.toml.orig	2018-11-22 08:28:30.000000000 +0000
+++ 2.4.0-1/Cargo.toml.orig	1973-11-29 21:33:09.000000000 +0000
@@ -1,6 +1,6 @@
 [package]
 name = "xdg"
-version = "2.2.0"
+version = "2.4.0"
 description = "A library for storing and retrieving files according to XDG Base Directory specification"
 homepage = "https://github.com/whitequark/rust-xdg"
 repository = "https://github.com/whitequark/rust-xdg"
@@ -15,3 +15,6 @@ authors = [
 
 [lib]
 doctest = false
+
+[dependencies]
+dirs = "3.0"
diff -pruN 2.2.0-3/.cargo_vcs_info.json 2.4.0-1/.cargo_vcs_info.json
--- 2.2.0-3/.cargo_vcs_info.json	1970-01-01 00:00:00.000000000 +0000
+++ 2.4.0-1/.cargo_vcs_info.json	1970-01-01 00:00:01.000000000 +0000
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "f404ae631b30f5fcb191f9fb65ff206721379d16"
+    "sha1": "1e2020a763e6b30d6bf9f4a69ab68d008a937f59"
   }
 }
diff -pruN 2.2.0-3/debian/changelog 2.4.0-1/debian/changelog
--- 2.2.0-3/debian/changelog	2020-06-09 06:56:24.000000000 +0000
+++ 2.4.0-1/debian/changelog	2022-08-05 10:41:51.000000000 +0000
@@ -1,9 +1,16 @@
+rust-xdg (2.4.0-1) unstable; urgency=medium
+
+  * Team upload.
+  * Package xdg 2.4.0 from crates.io using debcargo 2.5.0
+
+ -- James McCoy <jamessan@debian.org>  Fri, 05 Aug 2022 06:41:51 -0400
+
 rust-xdg (2.2.0-3) unstable; urgency=medium
 
   * Team upload.
   * Patch failing tests (Closes: #958398, #961460)
 
- -- Nikos Tsipinakis <nikos@tsipinakis.com>  Tue, 09 Jun 2020 08:56:24 +0200
+ -- Nikos Tsipinakis <nikos@tsipinakis.com>  Sat, 29 Aug 2020 10:58:22 +0200
 
 rust-xdg (2.2.0-2) unstable; urgency=medium
 
diff -pruN 2.2.0-3/debian/compat 2.4.0-1/debian/compat
--- 2.2.0-3/debian/compat	2020-06-09 06:56:24.000000000 +0000
+++ 2.4.0-1/debian/compat	2022-08-05 10:41:51.000000000 +0000
@@ -1 +1 @@
-11
+12
diff -pruN 2.2.0-3/debian/control 2.4.0-1/debian/control
--- 2.2.0-3/debian/control	2020-06-09 06:56:24.000000000 +0000
+++ 2.4.0-1/debian/control	2022-08-05 10:41:51.000000000 +0000
@@ -1,32 +1,35 @@
 Source: rust-xdg
 Section: rust
 Priority: optional
-Build-Depends: debhelper (>= 11),
- dh-cargo (>= 18),
+Build-Depends: debhelper (>= 12),
+ dh-cargo (>= 25),
  cargo:native <!nocheck>,
  rustc:native <!nocheck>,
- libstd-rust-dev <!nocheck>
+ libstd-rust-dev <!nocheck>,
+ librust-dirs-3+default-dev <!nocheck>
 Maintainer: Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
 Uploaders:
  Wolfgang Silbermayr <wolfgang@silbermayr.at>
-Standards-Version: 4.4.1
+Standards-Version: 4.5.1
 Vcs-Git: https://salsa.debian.org/rust-team/debcargo-conf.git [src/xdg]
 Vcs-Browser: https://salsa.debian.org/rust-team/debcargo-conf/tree/master/src/xdg
 Homepage: https://github.com/whitequark/rust-xdg
+Rules-Requires-Root: no
 
 Package: librust-xdg-dev
 Architecture: any
 Multi-Arch: same
 Depends:
- ${misc:Depends}
+ ${misc:Depends},
+ librust-dirs-3+default-dev
 Provides:
  librust-xdg+default-dev (= ${binary:Version}),
  librust-xdg-2-dev (= ${binary:Version}),
  librust-xdg-2+default-dev (= ${binary:Version}),
- librust-xdg-2.2-dev (= ${binary:Version}),
- librust-xdg-2.2+default-dev (= ${binary:Version}),
- librust-xdg-2.2.0-dev (= ${binary:Version}),
- librust-xdg-2.2.0+default-dev (= ${binary:Version})
+ librust-xdg-2.4-dev (= ${binary:Version}),
+ librust-xdg-2.4+default-dev (= ${binary:Version}),
+ librust-xdg-2.4.0-dev (= ${binary:Version}),
+ librust-xdg-2.4.0+default-dev (= ${binary:Version})
 Description: XDG Base Directory specification implementation - Rust source code
  This package contains the source for the Rust xdg crate, packaged by debcargo
  for use with cargo and dh-cargo.
diff -pruN 2.2.0-3/debian/copyright.debcargo.hint 2.4.0-1/debian/copyright.debcargo.hint
--- 2.2.0-3/debian/copyright.debcargo.hint	2020-06-09 06:56:24.000000000 +0000
+++ 2.4.0-1/debian/copyright.debcargo.hint	2022-08-05 10:41:51.000000000 +0000
@@ -25,8 +25,8 @@ Comment:
 
 Files: debian/*
 Copyright:
- 2019-2020 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
- 2019-2020 Wolfgang Silbermayr <wolfgang@silbermayr.at>
+ 2019-2022 Debian Rust Maintainers <pkg-rust-maintainers@alioth-lists.debian.net>
+ 2019-2022 Wolfgang Silbermayr <wolfgang@silbermayr.at>
 License: Apache-2.0 or MIT
 
 License: Apache-2.0
diff -pruN 2.2.0-3/debian/patches/test-use-env-target-path.patch 2.4.0-1/debian/patches/test-use-env-target-path.patch
--- 2.2.0-3/debian/patches/test-use-env-target-path.patch	2020-06-09 06:56:24.000000000 +0000
+++ 2.4.0-1/debian/patches/test-use-env-target-path.patch	2022-08-05 10:41:51.000000000 +0000
@@ -4,7 +4,7 @@ Last-Update: 2020-06-05
 
 --- a/src/lib.rs
 +++ b/src/lib.rs
-@@ -655,10 +655,19 @@
+@@ -746,10 +746,19 @@ fn list_files_once(home: &Path, dirs: &[
  }
  
  #[cfg(test)]
@@ -25,7 +25,7 @@ Last-Update: 2020-06-05
  #[cfg(test)]
  fn iter_after<A, I, J>(mut iter: I, mut prefix: J) -> Option<I> where
      I: Iterator<Item=A> + Clone, J: Iterator<Item=A>, A: PartialEq
-@@ -678,8 +687,8 @@
+@@ -769,8 +778,8 @@ fn iter_after<A, I, J>(mut iter: I, mut
  }
  
  #[cfg(test)]
@@ -36,7 +36,7 @@ Last-Update: 2020-06-05
          .unwrap().as_path().to_owned()
  }
  
-@@ -774,24 +783,24 @@
+@@ -865,24 +874,24 @@ fn test_runtime_good() {
      perms.set_mode(0o700);
      fs::set_permissions(&test_runtime_dir, perms).unwrap();
  
@@ -67,7 +67,7 @@ Last-Update: 2020-06-05
      root.sort();
      assert_eq!(root,
                 vec![PathBuf::from("test_files/runtime-good/bar"),
-@@ -799,7 +808,7 @@
+@@ -890,7 +899,7 @@ fn test_runtime_good() {
      assert!(xd.list_runtime_files("bar").is_empty());
      assert!(xd.find_runtime_file("foo/qux").is_none());
      assert!(xd.find_runtime_file("qux/foo").is_none());
@@ -76,7 +76,7 @@ Last-Update: 2020-06-05
  }
  
  #[test]
-@@ -815,7 +824,7 @@
+@@ -906,7 +915,7 @@ fn test_lists() {
          ])).unwrap();
  
      let files = xd.list_config_files(".");
@@ -85,7 +85,7 @@ Last-Update: 2020-06-05
      files.sort();
      assert_eq!(files,
          [
-@@ -832,7 +841,7 @@
+@@ -923,7 +932,7 @@ fn test_lists() {
          ].iter().map(PathBuf::from).collect::<Vec<_>>());
  
      let files = xd.list_config_files_once(".");
@@ -94,3 +94,20 @@ Last-Update: 2020-06-05
      files.sort();
      assert_eq!(files,
          [
+@@ -938,7 +947,7 @@ fn test_lists() {
+ 
+ #[test]
+ fn test_get_file() {
+-    let cwd = env::current_dir().unwrap().to_string_lossy().into_owned();
++    let cwd = get_test_dir().to_string_lossy().into_owned();
+     let xd = BaseDirectories::with_env("", "", &*make_env(vec![
+             ("HOME", format!("{}/test_files/user", cwd)),
+             ("XDG_DATA_HOME", format!("{}/test_files/user/data", cwd)),
+@@ -948,6 +957,7 @@ fn test_get_file() {
+         ])).unwrap();
+     
+     let path = format!("{}/test_files/user/runtime/", cwd);
++    fs::create_dir_all(&path).unwrap();
+     let metadata = fs::metadata(&path).expect("Could not read metadata for runtime directory");
+     let mut perms = metadata.permissions();
+     perms.set_mode(0o700);
diff -pruN 2.2.0-3/debian/tests/control 2.4.0-1/debian/tests/control
--- 2.2.0-3/debian/tests/control	2020-06-09 06:56:24.000000000 +0000
+++ 2.4.0-1/debian/tests/control	2022-08-05 10:41:51.000000000 +0000
@@ -1,9 +1,14 @@
-Test-Command: /usr/share/cargo/bin/cargo-auto-test xdg 2.2.0 --all-targets --all-features
-Features: test-name=@
+Test-Command: /usr/share/cargo/bin/cargo-auto-test xdg 2.4.0 --all-targets --all-features
+Features: test-name=rust-xdg:@
 Depends: dh-cargo (>= 18), @
 Restrictions: allow-stderr, skip-not-installable
 
-Test-Command: /usr/share/cargo/bin/cargo-auto-test xdg 2.2.0 --all-targets --no-default-features
-Features: test-name=librust-xdg-dev
+Test-Command: /usr/share/cargo/bin/cargo-auto-test xdg 2.4.0 --all-targets 
+Features: test-name=librust-xdg-dev:default
+Depends: dh-cargo (>= 18), @
+Restrictions: allow-stderr, skip-not-installable
+
+Test-Command: /usr/share/cargo/bin/cargo-auto-test xdg 2.4.0 --all-targets --no-default-features
+Features: test-name=librust-xdg-dev:
 Depends: dh-cargo (>= 18), @
 Restrictions: allow-stderr, skip-not-installable
diff -pruN 2.2.0-3/src/lib.rs 2.4.0-1/src/lib.rs
--- 2.2.0-3/src/lib.rs	2018-11-22 08:26:59.000000000 +0000
+++ 2.4.0-1/src/lib.rs	1973-11-29 21:33:09.000000000 +0000
@@ -1,5 +1,7 @@
 #![cfg(any(unix, target_os = "redox"))]
 
+extern crate dirs;
+
 use std::fmt;
 use std::convert;
 use std::error;
@@ -19,7 +21,7 @@ use BaseDirectoriesError as Error;
 /// the [X Desktop Group Base Directory specification][xdg-basedir].
 /// [xdg-basedir]: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
 ///
-/// The Base Directory specification defines four kinds of files:
+/// The Base Directory specification defines five kinds of files:
 ///
 ///   * **Configuration files** store the application's settings and
 ///     are often modified during runtime;
@@ -28,6 +30,8 @@ use BaseDirectoriesError as Error;
 ///     source code;
 ///   * **Cache files** store non-essential, transient data that provides
 ///     a runtime speedup;
+///   * **State files** store logs, history, recently used files and application
+///     state (window size, open files, unsaved changes, …);
 ///   * **Runtime files** include filesystem objects such are sockets or
 ///     named pipes that are used for communication internal to the application.
 ///     Runtime files must not be accessible to anyone except current user.
@@ -46,8 +50,8 @@ use BaseDirectoriesError as Error;
 /// ```
 /// let config_path = xdg_dirs.place_config_file("config.ini")
 ///                           .expect("cannot create configuration directory");
-/// let mut config_file = try!(File::create(config_path));
-/// try!(write!(&mut config_file, "configured = 1"));
+/// let mut config_file = File::create(config_path)?;
+/// write!(&mut config_file, "configured = 1")?;
 /// ```
 ///
 /// The `config.ini` file will appear in the proper location for desktop
@@ -59,9 +63,9 @@ use BaseDirectoriesError as Error;
 /// ```
 /// let logo_path = xdg_dirs.find_data_file("logo.png")
 ///                         .expect("application data not present");
-/// let mut logo_file = try!(File::open(logo_path));
+/// let mut logo_file = File::open(logo_path)?;
 /// let mut logo = Vec::new();
-/// try!(logo_file.read_to_end(&mut logo));
+/// logo_file.read_to_end(&mut logo)?;
 /// ```
 ///
 /// The `logo.png` will be searched in the proper locations for
@@ -74,6 +78,7 @@ pub struct BaseDirectories {
     data_home: PathBuf,
     config_home: PathBuf,
     cache_home: PathBuf,
+    state_home: PathBuf,
     data_dirs: Vec<PathBuf>,
     config_dirs: Vec<PathBuf>,
     runtime_dir: Option<PathBuf>,
@@ -109,7 +114,7 @@ impl error::Error for BaseDirectoriesErr
                 "$XDG_RUNTIME_DIR is not set",
         }
     }
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         match self.kind {
             XdgRuntimeDirInaccessible(_, ref e) => Some(e),
             _ => None,
@@ -120,7 +125,7 @@ impl error::Error for BaseDirectoriesErr
 impl fmt::Display for BaseDirectoriesError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.kind {
-            HomeMissing => write!(f, "{}", error::Error::description(self)),
+            HomeMissing => write!(f, "{}", self.to_string()),
             XdgRuntimeDirInaccessible(ref dir, ref error) => {
                 write!(f, "$XDG_RUNTIME_DIR (`{}`) must be accessible \
                            by the current user (error: {})", dir.display(), error)
@@ -176,11 +181,12 @@ impl BaseDirectories {
     /// and returns a value that can be used for lookup.
     /// The following environment variables are examined:
     ///
-    ///   * `HOME`; if not set: use the same fallback as `std::env::home_dir()`;
+    ///   * `HOME`; if not set: use the same fallback as `dirs::home_dir()`;
     ///     if still not available: return an error.
     ///   * `XDG_DATA_HOME`; if not set: assumed to be `$HOME/.local/share`.
     ///   * `XDG_CONFIG_HOME`; if not set: assumed to be `$HOME/.config`.
     ///   * `XDG_CACHE_HOME`; if not set: assumed to be `$HOME/.cache`.
+    ///   * `XDG_STATE_HOME`; if not set: assumed to be `$HOME/.local/state`.
     ///   * `XDG_DATA_DIRS`; if not set: assumed to be `/usr/local/share:/usr/share`.
     ///   * `XDG_CONFIG_DIRS`; if not set: assumed to be `/etc/xdg`.
     ///   * `XDG_RUNTIME_DIR`; if not accessible or permissions are not `0700`:
@@ -253,7 +259,7 @@ impl BaseDirectories {
             }
         }
 
-        let home = try!(std::env::home_dir().ok_or(Error::new(HomeMissing)));
+        let home = dirs::home_dir().ok_or(Error::new(HomeMissing))?;
 
         let data_home   = env_var("XDG_DATA_HOME")
                               .and_then(abspath)
@@ -264,6 +270,9 @@ impl BaseDirectories {
         let cache_home  = env_var("XDG_CACHE_HOME")
                               .and_then(abspath)
                               .unwrap_or(home.join(".cache"));
+        let state_home  = env_var("XDG_STATE_HOME")
+                              .and_then(abspath)
+                              .unwrap_or(home.join(".local/state"));
         let data_dirs   = env_var("XDG_DATA_DIRS")
                               .and_then(abspaths)
                               .unwrap_or(vec![PathBuf::from("/usr/local/share"),
@@ -278,25 +287,27 @@ impl BaseDirectories {
         Ok(BaseDirectories {
             user_prefix: prefix.join(profile),
             shared_prefix: prefix,
-            data_home: data_home,
-            config_home: config_home,
-            cache_home: cache_home,
-            data_dirs: data_dirs,
-            config_dirs: config_dirs,
-            runtime_dir: runtime_dir,
+            data_home,
+            config_home,
+            cache_home,
+            state_home,
+            data_dirs,
+            config_dirs,
+            runtime_dir,
         })
     }
 
-    fn get_runtime_directory(&self) -> Result<&PathBuf, BaseDirectoriesError> {
+    /// Returns the user-specific runtime directory (set by `XDG_RUNTIME_DIR`).
+    pub fn get_runtime_directory(&self) -> Result<&PathBuf, BaseDirectoriesError> {
         if let Some(ref runtime_dir) = self.runtime_dir {
             // If XDG_RUNTIME_DIR is in the environment but not secure,
             // do not allow recovery.
-            try!(fs::read_dir(runtime_dir).map_err(|e| {
+            fs::read_dir(runtime_dir).map_err(|e| {
                 Error::new(XdgRuntimeDirInaccessible(runtime_dir.clone(), e))
-            }));
-            let permissions = try!(fs::metadata(runtime_dir).map_err(|e| {
+            })?;
+            let permissions = fs::metadata(runtime_dir).map_err(|e| {
                 Error::new(XdgRuntimeDirInaccessible(runtime_dir.clone(), e))
-            })).permissions().mode() as u32;
+            })?.permissions().mode() as u32;
             if permissions & 0o077 != 0 {
                 Err(Error::new(XdgRuntimeDirInsecure(runtime_dir.clone(),
                                                      Permissions(permissions))))
@@ -316,6 +327,43 @@ impl BaseDirectories {
         }
     }
 
+    /// Like [`place_config_file()`](#method.place_config_file), but does
+    /// not create any directories.
+    pub fn get_config_file<P>(&self, path: P) -> PathBuf
+            where P: AsRef<Path> {
+        self.config_home.join(self.user_prefix.join(path))
+    }
+
+    /// Like [`place_data_file()`](#method.place_data_file), but does
+    /// not create any directories.
+    pub fn get_data_file<P>(&self, path: P) -> PathBuf
+            where P: AsRef<Path> {
+        self.data_home.join(self.user_prefix.join(path))
+    }
+
+    /// Like [`place_cache_file()`](#method.place_cache_file), but does
+    /// not create any directories.
+    pub fn get_cache_file<P>(&self, path: P) -> PathBuf
+            where P: AsRef<Path> {
+        self.cache_home.join(self.user_prefix.join(path))
+    }
+
+    /// Like [`place_state_file()`](#method.place_state_file), but does
+    /// not create any directories.
+    pub fn get_state_file<P>(&self, path: P) -> PathBuf
+            where P: AsRef<Path> {
+        self.state_home.join(self.user_prefix.join(path))
+    }
+
+    /// Like [`place_runtime_file()`](#method.place_runtime_file), but does
+    /// not create any directories.
+    /// If `XDG_RUNTIME_DIR` is not available, returns an error.
+    pub fn get_runtime_file<P>(&self, path: P) -> io::Result<PathBuf>
+            where P: AsRef<Path> {
+        let runtime_dir = self.get_runtime_directory()?;
+        Ok(runtime_dir.join(self.user_prefix.join(path)))
+    }
+
     /// Given a relative path `path`, returns an absolute path in
     /// `XDG_CONFIG_HOME` where a configuration file may be stored.
     /// Leading directories in the returned path are pre-created;
@@ -340,11 +388,18 @@ impl BaseDirectories {
     }
 
     /// Like [`place_config_file()`](#method.place_config_file), but for
+    /// an application state file in `XDG_STATE_HOME`.
+    pub fn place_state_file<P>(&self, path: P) -> io::Result<PathBuf>
+            where P: AsRef<Path> {
+        write_file(&self.state_home, self.user_prefix.join(path))
+    }
+
+    /// Like [`place_config_file()`](#method.place_config_file), but for
     /// a runtime file in `XDG_RUNTIME_DIR`.
     /// If `XDG_RUNTIME_DIR` is not available, returns an error.
     pub fn place_runtime_file<P>(&self, path: P) -> io::Result<PathBuf>
             where P: AsRef<Path> {
-        write_file(try!(self.get_runtime_directory()), self.user_prefix.join(path))
+        write_file(self.get_runtime_directory()?, self.user_prefix.join(path))
     }
 
     /// Given a relative path `path`, returns an absolute path to an existing
@@ -394,6 +449,14 @@ impl BaseDirectories {
     }
 
     /// Given a relative path `path`, returns an absolute path to an existing
+    /// application state file, or `None`. Searches `XDG_STATE_HOME`.
+    pub fn find_state_file<P>(&self, path: P) -> Option<PathBuf>
+            where P: AsRef<Path> {
+        read_file(&self.state_home, &Vec::new(),
+                  &self.user_prefix, &self.shared_prefix, path.as_ref())
+    }
+
+    /// Given a relative path `path`, returns an absolute path to an existing
     /// runtime file, or `None`. Searches `XDG_RUNTIME_DIR`.
     /// If `XDG_RUNTIME_DIR` is not available, returns `None`.
     pub fn find_runtime_file<P>(&self, path: P) -> Option<PathBuf>
@@ -433,11 +496,19 @@ impl BaseDirectories {
     }
 
     /// Like [`create_config_directory()`](#method.create_config_directory),
+    /// but for an application state directory in `XDG_STATE_HOME`.
+    pub fn create_state_directory<P>(&self, path: P) -> io::Result<PathBuf>
+            where P: AsRef<Path> {
+        create_directory(&self.state_home,
+                         self.user_prefix.join(path))
+    }
+
+    /// Like [`create_config_directory()`](#method.create_config_directory),
     /// but for a runtime directory in `XDG_RUNTIME_DIR`.
     /// If `XDG_RUNTIME_DIR` is not available, returns an error.
     pub fn create_runtime_directory<P>(&self, path: P) -> io::Result<PathBuf>
             where P: AsRef<Path> {
-        create_directory(try!(self.get_runtime_directory()),
+        create_directory(self.get_runtime_directory()?,
                          self.user_prefix.join(path))
     }
 
@@ -484,6 +555,14 @@ impl BaseDirectories {
     }
 
     /// Given a relative path `path`, lists absolute paths to all files
+    /// in directories with path `path` in `XDG_STATE_HOME`.
+    pub fn list_state_files<P>(&self, path: P) -> Vec<PathBuf>
+            where P: AsRef<Path> {
+        list_files(&self.state_home, &Vec::new(),
+                   &self.user_prefix, &self.shared_prefix, path.as_ref())
+    }
+
+    /// Given a relative path `path`, lists absolute paths to all files
     /// in directories with path `path` in `XDG_RUNTIME_DIR`.
     /// If `XDG_RUNTIME_DIR` is not available, returns an empty `Vec`.
     pub fn list_runtime_files<P>(&self, path: P) -> Vec<PathBuf>
@@ -513,6 +592,12 @@ impl BaseDirectories {
         self.cache_home.join(&self.user_prefix)
     }
 
+    /// Returns the user-specific directory for application state data
+    /// (set by `XDG_STATE_HOME`).
+    pub fn get_state_home(&self) -> PathBuf {
+        self.state_home.join(&self.user_prefix)
+    }
+
     /// Returns a preference ordered (preferred to less preferred) list of
     /// supplementary data directories, ordered by preference (set by
     /// `XDG_DATA_DIRS`).
@@ -530,8 +615,8 @@ impl BaseDirectories {
 fn write_file<P>(home: &PathBuf, path: P) -> io::Result<PathBuf>
         where P: AsRef<Path> {
     match path.as_ref().parent() {
-        Some(parent) => try!(fs::create_dir_all(home.join(parent))),
-        None => try!(fs::create_dir_all(home)),
+        Some(parent) => fs::create_dir_all(home.join(parent))?,
+        None => fs::create_dir_all(home)?,
     }
     Ok(PathBuf::from(home.join(path.as_ref())))
 }
@@ -539,7 +624,7 @@ fn write_file<P>(home: &PathBuf, path: P
 fn create_directory<P>(home: &PathBuf, path: P) -> io::Result<PathBuf>
         where P: AsRef<Path> {
     let full_path = home.join(path.as_ref());
-    try!(fs::create_dir_all(&full_path));
+    fs::create_dir_all(&full_path)?;
     Ok(full_path)
 }
 
@@ -574,10 +659,9 @@ fn read_file(home: &PathBuf, dirs: &Vec<
     None
 }
 
-use std::iter::Iterator;
+use std::vec::IntoIter as VecIter;
 pub struct FileFindIterator {
-    search_dirs: Vec<PathBuf>,
-    position: usize,
+    search_dirs: VecIter<PathBuf>,
     relpath: PathBuf,
 }
 
@@ -591,8 +675,7 @@ impl FileFindIterator {
        }
        search_dirs.push(home.join(user_prefix));
        FileFindIterator {
-           search_dirs: search_dirs,
-           position: 0,
+           search_dirs: search_dirs.into_iter(),
            relpath: path.to_path_buf(),
        }
    }
@@ -603,11 +686,19 @@ impl Iterator for FileFindIterator {
 
     fn next(&mut self) -> Option<Self::Item> {
         loop {
-            let dir = match self.search_dirs.get(self.position) {
-                Some(d) => d,
-                None => return None
-            };
-            self.position += 1;
+            let dir = self.search_dirs.next()?;
+            let candidate = dir.join(self.relpath.clone());
+            if path_exists(&candidate) {
+                return Some(candidate)
+            }
+        }
+    }
+}
+
+impl DoubleEndedIterator for FileFindIterator {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        loop {
+            let dir = self.search_dirs.next_back()?;
             let candidate = dir.join(self.relpath.clone());
             if path_exists(&candidate) {
                 return Some(candidate)
@@ -685,7 +776,7 @@ fn make_relative<P>(path: P) -> PathBuf
 
 #[cfg(test)]
 fn make_env(vars: Vec<(&'static str, String)>) ->
-        Box<Fn(&str)->Option<OsString>> {
+        Box<dyn Fn(&str)->Option<OsString>> {
     return Box::new(move |name| {
         for &(key, ref value) in vars.iter() {
             if key == name { return Some(OsString::from(value)) }
@@ -846,12 +937,44 @@ fn test_lists() {
 }
 
 #[test]
+fn test_get_file() {
+    let cwd = env::current_dir().unwrap().to_string_lossy().into_owned();
+    let xd = BaseDirectories::with_env("", "", &*make_env(vec![
+            ("HOME", format!("{}/test_files/user", cwd)),
+            ("XDG_DATA_HOME", format!("{}/test_files/user/data", cwd)),
+            ("XDG_CONFIG_HOME", format!("{}/test_files/user/config", cwd)),
+            ("XDG_CACHE_HOME", format!("{}/test_files/user/cache", cwd)),
+            ("XDG_RUNTIME_DIR", format!("{}/test_files/user/runtime", cwd)),
+        ])).unwrap();
+    
+    let path = format!("{}/test_files/user/runtime/", cwd);
+    let metadata = fs::metadata(&path).expect("Could not read metadata for runtime directory");
+    let mut perms = metadata.permissions();
+    perms.set_mode(0o700);
+    fs::set_permissions(&path, perms).expect("Could not set permissions for runtime directory");
+
+    let file = xd.get_config_file("myapp/user_config.file");
+    assert_eq!(file, PathBuf::from(&format!("{}/test_files/user/config/myapp/user_config.file", cwd)));
+
+    let file = xd.get_data_file("user_data.file");
+    assert_eq!(file, PathBuf::from(&format!("{}/test_files/user/data/user_data.file", cwd)));
+
+    let file = xd.get_cache_file("user_cache.file");
+    assert_eq!(file, PathBuf::from(&format!("{}/test_files/user/cache/user_cache.file", cwd)));
+
+    let file = xd.get_runtime_file("user_runtime.file").unwrap();
+    assert_eq!(file, PathBuf::from(&format!("{}/test_files/user/runtime/user_runtime.file", cwd)));
+}
+
+#[test]
 fn test_prefix() {
     let cwd = env::current_dir().unwrap().to_string_lossy().into_owned();
     let xd = BaseDirectories::with_env("myapp", "", &*make_env(vec![
             ("HOME", format!("{}/test_files/user", cwd)),
             ("XDG_CACHE_HOME", format!("{}/test_files/user/cache", cwd)),
         ])).unwrap();
+    assert_eq!(xd.get_cache_file("cache.db"),
+        PathBuf::from(&format!("{}/test_files/user/cache/myapp/cache.db", cwd)));
     assert_eq!(xd.place_cache_file("cache.db").unwrap(),
                PathBuf::from(&format!("{}/test_files/user/cache/myapp/cache.db", cwd)));
 }
@@ -871,3 +994,25 @@ fn test_profile() {
                // Includes default_profile
                PathBuf::from(&format!("{}/test_files/user/config/myapp/default_profile/user_config.file", cwd)));
 }
+
+/// Ensure that entries in XDG_CONFIG_DIRS can be replaced with symlinks.
+#[test]
+fn test_symlinks() {
+    let cwd = env::current_dir().unwrap().to_string_lossy().into_owned();
+    let symlinks_dir = format!("{}/test_files/symlinks", cwd);
+    let config_dir = format!("{}/config", symlinks_dir);
+    let myapp_dir = format!("{}/myapp", config_dir);
+
+    assert!(path_exists(&myapp_dir));
+    assert!(path_exists(&config_dir));
+    assert!(path_exists(&symlinks_dir));
+
+    let xd = BaseDirectories::with_env(
+        "myapp", "", &*make_env(vec![
+            ("HOME", symlinks_dir),
+            ("XDG_CONFIG_HOME", config_dir),
+        ])
+    ).unwrap();
+    assert_eq!(xd.find_config_file("user_config.file").unwrap(),
+               PathBuf::from(&format!("{}/user_config.file", myapp_dir)));
+}
