diff --git a/Library/Homebrew/cask/lib/hbc/cask.rb b/Library/Homebrew/cask/lib/hbc/cask.rb
index cf5f2b37a9b4760988fbf5f11179f0896133e66b..a193a394e9142ef30e193d7ba22edc3fbf4e8402 100644
--- a/Library/Homebrew/cask/lib/hbc/cask.rb
+++ b/Library/Homebrew/cask/lib/hbc/cask.rb
@@ -1,10 +1,12 @@
 require "forwardable"
 
 require "hbc/dsl"
+require "hbc/metadata"
 
 module Hbc
   class Cask
     extend Forwardable
+    include Metadata
 
     attr_reader :token, :sourcefile_path
     def initialize(token, sourcefile_path: nil, &block)
@@ -20,55 +22,9 @@ module Hbc
       define_method(method_name) { @dsl.send(method_name) }
     end
 
-    METADATA_SUBDIR = ".metadata".freeze
-
-    def metadata_master_container_path
-      @metadata_master_container_path ||= caskroom_path.join(METADATA_SUBDIR)
-    end
-
-    def metadata_versioned_container_path
-      cask_version = version ? version : :unknown
-      metadata_master_container_path.join(cask_version.to_s)
-    end
-
-    def metadata_path(timestamp = :latest, create = false)
-      if create && timestamp == :latest
-        raise CaskError, "Cannot create metadata path when timestamp is :latest"
-      end
-      path = if timestamp == :latest
-        Pathname.glob(metadata_versioned_container_path.join("*")).sort.last
-      elsif timestamp == :now
-        Utils.nowstamp_metadata_path(metadata_versioned_container_path)
-      else
-        metadata_versioned_container_path.join(timestamp)
-      end
-      if create
-        odebug "Creating metadata directory #{path}"
-        FileUtils.mkdir_p path
-      end
-      path
-    end
-
-    def metadata_subdir(leaf, timestamp = :latest, create = false)
-      if create && timestamp == :latest
-        raise CaskError, "Cannot create metadata subdir when timestamp is :latest"
-      end
-      unless leaf.respond_to?(:length) && !leaf.empty?
-        raise CaskError, "Cannot create metadata subdir for empty leaf"
-      end
-      parent = metadata_path(timestamp, create)
-      return nil unless parent.respond_to?(:join)
-      subdir = parent.join(leaf)
-      if create
-        odebug "Creating metadata subdirectory #{subdir}"
-        FileUtils.mkdir_p subdir
-      end
-      subdir
-    end
-
     def timestamped_versions
-      Pathname.glob(metadata_master_container_path.join("*", "*"))
-              .map { |p| p.relative_path_from(metadata_master_container_path) }
+      Pathname.glob(metadata_timestamped_path(version: "*", timestamp: "*"))
+              .map { |p| p.relative_path_from(p.parent.parent) }
               .sort_by(&:basename) # sort by timestamp
               .map { |p| p.split.map(&:to_s) }
     end
diff --git a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb
index 6887aaf4fc4162f90ff8098982afcfd6897c7ad3..1ee3230ad87b80b0bdb5a289a79eed7579fa2003 100644
--- a/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb
+++ b/Library/Homebrew/cask/lib/hbc/cli/uninstall.rb
@@ -12,15 +12,9 @@ module Hbc
 
           raise CaskNotInstalledError, cask unless cask.installed? || force
 
-          latest_installed_version = cask.timestamped_versions.last
-
-          unless latest_installed_version.nil?
-            latest_installed_cask_file = cask.metadata_master_container_path
-                                             .join(latest_installed_version.join(File::Separator),
-                                                   "Casks", "#{cask_token}.rb")
-
+          if cask.installed? && !cask.installed_caskfile.nil?
             # use the same cask file that was used for installation, if possible
-            cask = CaskLoader.load_from_file(latest_installed_cask_file) if latest_installed_cask_file.exist?
+            cask = CaskLoader.load_from_file(cask.installed_caskfile) if cask.installed_caskfile.exist?
           end
 
           Installer.new(cask, force: force).uninstall
diff --git a/Library/Homebrew/cask/lib/hbc/installer.rb b/Library/Homebrew/cask/lib/hbc/installer.rb
index 824c1b1beb5be6529153669da7dba6bbceeb6dd6..26022953b98ada02eeab49856bf29794b9286760 100644
--- a/Library/Homebrew/cask/lib/hbc/installer.rb
+++ b/Library/Homebrew/cask/lib/hbc/installer.rb
@@ -295,15 +295,13 @@ module Hbc
     end
 
     def save_caskfile
-      unless (old_savedirs = Pathname.glob(@cask.metadata_path("*"))).empty?
-        old_savedirs.each(&:rmtree)
-      end
+      old_savedir = @cask.metadata_timestamped_path
 
       return unless @cask.sourcefile_path
 
-      savedir = @cask.metadata_subdir("Casks", :now, true)
-      savedir.mkpath
+      savedir = @cask.metadata_subdir("Casks", timestamp: :now, create: true)
       FileUtils.copy @cask.sourcefile_path, savedir
+      old_savedir.rmtree unless old_savedir.nil?
     end
 
     def uninstall
@@ -355,15 +353,15 @@ module Hbc
       gain_permissions_remove(@cask.staged_path) if !@cask.staged_path.nil? && @cask.staged_path.exist?
 
       # Homebrew-Cask metadata
-      if @cask.metadata_versioned_container_path.respond_to?(:children) &&
-         @cask.metadata_versioned_container_path.exist?
-        @cask.metadata_versioned_container_path.children.each do |subdir|
+      if @cask.metadata_versioned_path.respond_to?(:children) &&
+         @cask.metadata_versioned_path.exist?
+        @cask.metadata_versioned_path.children.each do |subdir|
           unless PERSISTENT_METADATA_SUBDIRS.include?(subdir.basename)
             gain_permissions_remove(subdir)
           end
         end
       end
-      @cask.metadata_versioned_container_path.rmdir_if_possible
+      @cask.metadata_versioned_path.rmdir_if_possible
       @cask.metadata_master_container_path.rmdir_if_possible
 
       # toplevel staged distribution
diff --git a/Library/Homebrew/cask/lib/hbc/metadata.rb b/Library/Homebrew/cask/lib/hbc/metadata.rb
new file mode 100644
index 0000000000000000000000000000000000000000..344c38ceeaac01e1b73c2281c40fdaadee6fc1a8
--- /dev/null
+++ b/Library/Homebrew/cask/lib/hbc/metadata.rb
@@ -0,0 +1,73 @@
+module Hbc
+  module Metadata
+    METADATA_SUBDIR = ".metadata".freeze
+
+    def metadata_master_container_path
+      @metadata_master_container_path ||= caskroom_path.join(METADATA_SUBDIR)
+    end
+
+    def metadata_versioned_path(version: self.version)
+      cask_version = (version || :unknown).to_s
+
+      if cask_version.empty?
+        raise CaskError, "Cannot create metadata path with empty version."
+      end
+
+      metadata_master_container_path.join(cask_version)
+    end
+
+    def metadata_timestamped_path(version: self.version, timestamp: :latest, create: false)
+      if create && timestamp == :latest
+        raise CaskError, "Cannot create metadata path when timestamp is :latest."
+      end
+
+      path = if timestamp == :latest
+        Pathname.glob(metadata_versioned_path(version: version).join("*")).sort.last
+      else
+        timestamp = new_timestamp if timestamp == :now
+        metadata_versioned_path(version: version).join(timestamp)
+      end
+
+      if create && !path.directory?
+        odebug "Creating metadata directory #{path}."
+        path.mkpath
+      end
+
+      path
+    end
+
+    def metadata_subdir(leaf, version: self.version, timestamp: :latest, create: false)
+      if create && timestamp == :latest
+        raise CaskError, "Cannot create metadata subdir when timestamp is :latest."
+      end
+
+      unless leaf.respond_to?(:empty?) && !leaf.empty?
+        raise CaskError, "Cannot create metadata subdir for empty leaf."
+      end
+
+      parent = metadata_timestamped_path(version: version, timestamp: timestamp, create: create)
+
+      return nil if parent.nil?
+
+      subdir = parent.join(leaf)
+
+      if create && !subdir.directory?
+        odebug "Creating metadata subdirectory #{subdir}."
+        subdir.mkpath
+      end
+
+      subdir
+    end
+
+    private
+
+    def new_timestamp(time = Time.now)
+      time = time.utc
+
+      timestamp = time.strftime("%Y%m%d%H%M%S")
+      fraction = format("%.3f", time.to_f - time.to_i)[1..-1]
+
+      timestamp.concat(fraction)
+    end
+  end
+end
diff --git a/Library/Homebrew/cask/lib/hbc/utils.rb b/Library/Homebrew/cask/lib/hbc/utils.rb
index ecb565e8e34642be20c6f3612798814e5a9add3f..2a5acbc88cb1e3eb40eb636775a50e203d54ef03 100644
--- a/Library/Homebrew/cask/lib/hbc/utils.rb
+++ b/Library/Homebrew/cask/lib/hbc/utils.rb
@@ -115,16 +115,5 @@ module Hbc
 
       opoo(poo.join(" ") + "\n" + error_message_with_suggestions)
     end
-
-    def self.nowstamp_metadata_path(container_path)
-      @timenow ||= Time.now.gmtime
-      return unless container_path.respond_to?(:join)
-
-      precision = 3
-      timestamp = @timenow.strftime("%Y%m%d%H%M%S")
-      fraction = format("%.#{precision}f", @timenow.to_f - @timenow.to_i)[1..-1]
-      timestamp.concat(fraction)
-      container_path.join(timestamp)
-    end
   end
 end
diff --git a/Library/Homebrew/test/cask/cask_spec.rb b/Library/Homebrew/test/cask/cask_spec.rb
index 2ab966f82812a5e25814d4036d27502884c710c7..3736f3c01556ea2a0225c96efc242ffbe51e35c2 100644
--- a/Library/Homebrew/test/cask/cask_spec.rb
+++ b/Library/Homebrew/test/cask/cask_spec.rb
@@ -85,8 +85,8 @@ describe Hbc::Cask, :cask do
     it "proposes a versioned metadata directory name for each instance" do
       cask_token = "local-caffeine"
       c = Hbc::CaskLoader.load(cask_token)
-      metadata_path = Hbc.caskroom.join(cask_token, ".metadata", c.version)
-      expect(c.metadata_versioned_container_path.to_s).to eq(metadata_path.to_s)
+      metadata_timestamped_path = Hbc.caskroom.join(cask_token, ".metadata", c.version)
+      expect(c.metadata_versioned_path.to_s).to eq(metadata_timestamped_path.to_s)
     end
   end
 
diff --git a/Library/Homebrew/test/cask/installer_spec.rb b/Library/Homebrew/test/cask/installer_spec.rb
index 7dd5b2bda6857f7d2fbd8e5883ac54a14cfe666d..59d61bbdde3904505cc3d9e6faf229409ec93801 100644
--- a/Library/Homebrew/test/cask/installer_spec.rb
+++ b/Library/Homebrew/test/cask/installer_spec.rb
@@ -336,9 +336,8 @@ describe Hbc::Installer, :cask do
         Hbc::Installer.new(caffeine).install
       end
 
-      m_path = caffeine.metadata_path(:now, true)
-      expect(caffeine.metadata_path(:now, false)).to eq(m_path)
-      expect(caffeine.metadata_path(:latest)).to eq(m_path)
+      m_path = caffeine.metadata_timestamped_path(timestamp: :now, create: true)
+      expect(caffeine.metadata_timestamped_path(timestamp: :latest)).to eq(m_path)
     end
 
     it "generates and finds a metadata subdirectory for an installed Cask" do
@@ -349,9 +348,8 @@ describe Hbc::Installer, :cask do
       end
 
       subdir_name = "Casks"
-      m_subdir = caffeine.metadata_subdir(subdir_name, :now, true)
-      expect(caffeine.metadata_subdir(subdir_name, :now, false)).to eq(m_subdir)
-      expect(caffeine.metadata_subdir(subdir_name, :latest)).to eq(m_subdir)
+      m_subdir = caffeine.metadata_subdir(subdir_name, timestamp: :now, create: true)
+      expect(caffeine.metadata_subdir(subdir_name, timestamp: :latest)).to eq(m_subdir)
     end
   end