diff --git a/daemon/create.go b/daemon/create.go
index 16b6b48b92..ba0a2bf0c4 100644
--- a/daemon/create.go
+++ b/daemon/create.go
@@ -59,7 +59,7 @@ func (daemon *Daemon) Create(config *runconfig.Config, hostConfig *runconfig.Hos
 		if err != nil {
 			return nil, nil, err
 		}
-		if err = img.CheckDepth(); err != nil {
+		if err = daemon.graph.CheckDepth(img); err != nil {
 			return nil, nil, err
 		}
 		imgID = img.ID
diff --git a/daemon/image_delete.go b/daemon/image_delete.go
index 4340df8001..8056a87c86 100644
--- a/daemon/image_delete.go
+++ b/daemon/image_delete.go
@@ -160,7 +160,7 @@ func (daemon *Daemon) canDeleteImage(imgID string, force bool) error {
 			return err
 		}
 
-		if err := parent.WalkHistory(func(p *image.Image) error {
+		if err := daemon.graph.WalkHistory(parent, func(p *image.Image) error {
 			if imgID == p.ID {
 				if container.IsRunning() {
 					if force {
diff --git a/graph/graph.go b/graph/graph.go
index e95887fab8..b405e1dd87 100644
--- a/graph/graph.go
+++ b/graph/graph.go
@@ -3,12 +3,14 @@ package graph
 import (
 	"compress/gzip"
 	"crypto/sha256"
+	"encoding/json"
 	"fmt"
 	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
 	"runtime"
+	"strconv"
 	"strings"
 	"syscall"
 	"time"
@@ -29,7 +31,7 @@ import (
 
 // A Graph is a store for versioned filesystem images and the relationship between them.
 type Graph struct {
-	Root    string
+	root    string
 	idIndex *truncindex.TruncIndex
 	driver  graphdriver.Driver
 }
@@ -47,7 +49,7 @@ func NewGraph(root string, driver graphdriver.Driver) (*Graph, error) {
 	}
 
 	graph := &Graph{
-		Root:    abspath,
+		root:    abspath,
 		idIndex: truncindex.NewTruncIndex([]string{}),
 		driver:  driver,
 	}
@@ -58,7 +60,7 @@ func NewGraph(root string, driver graphdriver.Driver) (*Graph, error) {
 }
 
 func (graph *Graph) restore() error {
-	dir, err := ioutil.ReadDir(graph.Root)
+	dir, err := ioutil.ReadDir(graph.root)
 	if err != nil {
 		return err
 	}
@@ -95,14 +97,13 @@ func (graph *Graph) Get(name string) (*image.Image, error) {
 	if err != nil {
 		return nil, fmt.Errorf("could not find image: %v", err)
 	}
-	img, err := image.LoadImage(graph.ImageRoot(id))
+	img, err := graph.loadImage(id)
 	if err != nil {
 		return nil, err
 	}
 	if img.ID != id {
 		return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.ID)
 	}
-	img.SetGraph(graph)
 
 	if img.Size < 0 {
 		size, err := graph.driver.DiffSize(img.ID, img.Parent)
@@ -111,7 +112,7 @@ func (graph *Graph) Get(name string) (*image.Image, error) {
 		}
 
 		img.Size = size
-		if err := img.SaveSize(graph.ImageRoot(id)); err != nil {
+		if err := graph.saveSize(graph.imageRoot(id), int(img.Size)); err != nil {
 			return nil, err
 		}
 	}
@@ -164,7 +165,7 @@ func (graph *Graph) Register(img *image.Image, layerData archive.ArchiveReader)
 	// Ensure that the image root does not exist on the filesystem
 	// when it is not registered in the graph.
 	// This is common when you switch from one graph driver to another
-	if err := os.RemoveAll(graph.ImageRoot(img.ID)); err != nil && !os.IsNotExist(err) {
+	if err := os.RemoveAll(graph.imageRoot(img.ID)); err != nil && !os.IsNotExist(err) {
 		return err
 	}
 
@@ -174,10 +175,10 @@ func (graph *Graph) Register(img *image.Image, layerData archive.ArchiveReader)
 	// (FIXME: make that mandatory for drivers).
 	graph.driver.Remove(img.ID)
 
-	tmp, err := graph.Mktemp("")
+	tmp, err := graph.mktemp("")
 	defer os.RemoveAll(tmp)
 	if err != nil {
-		return fmt.Errorf("Mktemp failed: %s", err)
+		return fmt.Errorf("mktemp failed: %s", err)
 	}
 
 	// Create root filesystem in the driver
@@ -185,12 +186,11 @@ func (graph *Graph) Register(img *image.Image, layerData archive.ArchiveReader)
 		return fmt.Errorf("Driver %s failed to create image rootfs %s: %s", graph.driver, img.ID, err)
 	}
 	// Apply the diff/layer
-	img.SetGraph(graph)
-	if err := image.StoreImage(img, layerData, tmp); err != nil {
+	if err := graph.storeImage(img, layerData, tmp); err != nil {
 		return err
 	}
 	// Commit
-	if err := os.Rename(tmp, graph.ImageRoot(img.ID)); err != nil {
+	if err := os.Rename(tmp, graph.imageRoot(img.ID)); err != nil {
 		return err
 	}
 	graph.idIndex.Add(img.ID)
@@ -200,17 +200,16 @@ func (graph *Graph) Register(img *image.Image, layerData archive.ArchiveReader)
 // TempLayerArchive creates a temporary archive of the given image's filesystem layer.
 //   The archive is stored on disk and will be automatically deleted as soon as has been read.
 //   If output is not nil, a human-readable progress bar will be written to it.
-//   FIXME: does this belong in Graph? How about MktempFile, let the caller use it for archives?
 func (graph *Graph) TempLayerArchive(id string, sf *streamformatter.StreamFormatter, output io.Writer) (*archive.TempArchive, error) {
 	image, err := graph.Get(id)
 	if err != nil {
 		return nil, err
 	}
-	tmp, err := graph.Mktemp("")
+	tmp, err := graph.mktemp("")
 	if err != nil {
 		return nil, err
 	}
-	a, err := image.TarLayer()
+	a, err := graph.TarLayer(image)
 	if err != nil {
 		return nil, err
 	}
@@ -227,9 +226,9 @@ func (graph *Graph) TempLayerArchive(id string, sf *streamformatter.StreamFormat
 	return archive.NewTempArchive(progressReader, tmp)
 }
 
-// Mktemp creates a temporary sub-directory inside the graph's filesystem.
-func (graph *Graph) Mktemp(id string) (string, error) {
-	dir := filepath.Join(graph.Root, "_tmp", stringid.GenerateRandomID())
+// mktemp creates a temporary sub-directory inside the graph's filesystem.
+func (graph *Graph) mktemp(id string) (string, error) {
+	dir := filepath.Join(graph.root, "_tmp", stringid.GenerateRandomID())
 	if err := system.MkdirAll(dir, 0700); err != nil {
 		return "", err
 	}
@@ -237,7 +236,7 @@ func (graph *Graph) Mktemp(id string) (string, error) {
 }
 
 func (graph *Graph) newTempFile() (*os.File, error) {
-	tmp, err := graph.Mktemp("")
+	tmp, err := graph.mktemp("")
 	if err != nil {
 		return nil, err
 	}
@@ -342,17 +341,17 @@ func (graph *Graph) Delete(name string) error {
 	if err != nil {
 		return err
 	}
-	tmp, err := graph.Mktemp("")
+	tmp, err := graph.mktemp("")
 	graph.idIndex.Delete(id)
 	if err == nil {
-		if err := os.Rename(graph.ImageRoot(id), tmp); err != nil {
+		if err := os.Rename(graph.imageRoot(id), tmp); err != nil {
 			// On err make tmp point to old dir and cleanup unused tmp dir
 			os.RemoveAll(tmp)
-			tmp = graph.ImageRoot(id)
+			tmp = graph.imageRoot(id)
 		}
 	} else {
 		// On err make tmp point to old dir for cleanup
-		tmp = graph.ImageRoot(id)
+		tmp = graph.imageRoot(id)
 	}
 	// Remove rootfs data from the driver
 	graph.driver.Remove(id)
@@ -375,7 +374,7 @@ func (graph *Graph) Map() (map[string]*image.Image, error) {
 // walkAll iterates over each image in the graph, and passes it to a handler.
 // The walking order is undetermined.
 func (graph *Graph) walkAll(handler func(*image.Image)) error {
-	files, err := ioutil.ReadDir(graph.Root)
+	files, err := ioutil.ReadDir(graph.root)
 	if err != nil {
 		return err
 	}
@@ -428,10 +427,125 @@ func (graph *Graph) Heads() (map[string]*image.Image, error) {
 	return heads, err
 }
 
-func (graph *Graph) ImageRoot(id string) string {
-	return filepath.Join(graph.Root, id)
+func (graph *Graph) imageRoot(id string) string {
+	return filepath.Join(graph.root, id)
 }
 
-func (graph *Graph) Driver() graphdriver.Driver {
-	return graph.driver
+// storeImage stores file system layer data for the given image to the
+// graph's storage driver. Image metadata is stored in a file
+// at the specified root directory.
+func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader, root string) (err error) {
+	// Store the layer. If layerData is not nil, unpack it into the new layer
+	if layerData != nil {
+		if img.Size, err = graph.driver.ApplyDiff(img.ID, img.Parent, layerData); err != nil {
+			return err
+		}
+	}
+
+	if err := graph.saveSize(root, int(img.Size)); err != nil {
+		return err
+	}
+
+	f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
+	if err != nil {
+		return err
+	}
+
+	defer f.Close()
+
+	return json.NewEncoder(f).Encode(img)
+}
+
+// loadImage fetches the image with the given id from the graph.
+func (graph *Graph) loadImage(id string) (*image.Image, error) {
+	root := graph.imageRoot(id)
+
+	// Open the JSON file to decode by streaming
+	jsonSource, err := os.Open(jsonPath(root))
+	if err != nil {
+		return nil, err
+	}
+	defer jsonSource.Close()
+
+	img := &image.Image{}
+	dec := json.NewDecoder(jsonSource)
+
+	// Decode the JSON data
+	if err := dec.Decode(img); err != nil {
+		return nil, err
+	}
+	if err := image.ValidateID(img.ID); err != nil {
+		return nil, err
+	}
+
+	if buf, err := ioutil.ReadFile(filepath.Join(root, "layersize")); err != nil {
+		if !os.IsNotExist(err) {
+			return nil, err
+		}
+		// If the layersize file does not exist then set the size to a negative number
+		// because a layer size of 0 (zero) is valid
+		img.Size = -1
+	} else {
+		// Using Atoi here instead would temporarily convert the size to a machine
+		// dependent integer type, which causes images larger than 2^31 bytes to
+		// display negative sizes on 32-bit machines:
+		size, err := strconv.ParseInt(string(buf), 10, 64)
+		if err != nil {
+			return nil, err
+		}
+		img.Size = int64(size)
+	}
+
+	return img, nil
+}
+
+// saveSize stores the `size` in the provided graph `img` directory `root`.
+func (graph *Graph) saveSize(root string, size int) error {
+	if err := ioutil.WriteFile(filepath.Join(root, "layersize"), []byte(strconv.Itoa(size)), 0600); err != nil {
+		return fmt.Errorf("Error storing image size in %s/layersize: %s", root, err)
+	}
+	return nil
+}
+
+// SetCheckSum sets the checksum for the image layer to the provided value.
+func (graph *Graph) SetCheckSum(id, checksum string) error {
+	root := graph.imageRoot(id)
+	if err := ioutil.WriteFile(filepath.Join(root, "checksum"), []byte(checksum), 0600); err != nil {
+		return fmt.Errorf("Error storing checksum in %s/checksum: %s", root, err)
+	}
+	return nil
+}
+
+// GetCheckSum gets the checksum for the provide image layer id.
+func (graph *Graph) GetCheckSum(id string) (string, error) {
+	root := graph.imageRoot(id)
+	cs, err := ioutil.ReadFile(filepath.Join(root, "checksum"))
+	if err != nil {
+		if os.IsNotExist(err) {
+			return "", nil
+		}
+		return "", err
+	}
+	return string(cs), err
+}
+
+// RawJSON returns the JSON representation for an image as a byte array.
+func (graph *Graph) RawJSON(id string) ([]byte, error) {
+	root := graph.imageRoot(id)
+
+	buf, err := ioutil.ReadFile(jsonPath(root))
+	if err != nil {
+		return nil, fmt.Errorf("Failed to read json for image %s: %s", id, err)
+	}
+
+	return buf, nil
+}
+
+func jsonPath(root string) string {
+	return filepath.Join(root, "json")
+}
+
+// TarLayer returns a tar archive of the image's filesystem layer.
+func (graph *Graph) TarLayer(img *image.Image) (arch archive.Archive, err error) {
+	return graph.driver.Diff(img.ID, img.Parent)
 }
diff --git a/graph/graph_test.go b/graph/graph_test.go
index 81471b6749..71c84b0894 100644
--- a/graph/graph_test.go
+++ b/graph/graph_test.go
@@ -17,7 +17,7 @@ import (
 
 func TestMount(t *testing.T) {
 	graph, driver := tempGraph(t)
-	defer os.RemoveAll(graph.Root)
+	defer os.RemoveAll(graph.root)
 	defer driver.Cleanup()
 
 	archive, err := fakeTar()
@@ -52,7 +52,7 @@ func TestInit(t *testing.T) {
 	graph, _ := tempGraph(t)
 	defer nukeGraph(graph)
 	// Root should exist
-	if _, err := os.Stat(graph.Root); err != nil {
+	if _, err := os.Stat(graph.root); err != nil {
 		t.Fatal(err)
 	}
 	// Map() should be empty
@@ -301,6 +301,6 @@ func tempGraph(t *testing.T) (*Graph, graphdriver.Driver) {
 }
 
 func nukeGraph(graph *Graph) {
-	graph.Driver().Cleanup()
-	os.RemoveAll(graph.Root)
+	graph.driver.Cleanup()
+	os.RemoveAll(graph.root)
 }
diff --git a/graph/history.go b/graph/history.go
index 56e759a8eb..280e7c8358 100644
--- a/graph/history.go
+++ b/graph/history.go
@@ -1,6 +1,7 @@
 package graph
 
 import (
+	"fmt"
 	"strings"
 
 	"github.com/docker/docker/api/types"
@@ -8,6 +9,78 @@ import (
 	"github.com/docker/docker/utils"
 )
 
+// History returns the list of all images used to create this image.
+func (graph *Graph) History(img *image.Image) ([]*image.Image, error) {
+	var parents []*image.Image
+	if err := graph.WalkHistory(img,
+		func(img *image.Image) error {
+			parents = append(parents, img)
+			return nil
+		},
+	); err != nil {
+		return nil, err
+	}
+	return parents, nil
+}
+
+// WalkHistory calls the handler function for each image in the
+// provided images lineage starting from immediate parent.
+func (graph *Graph) WalkHistory(img *image.Image, handler func(*image.Image) error) (err error) {
+	currentImg := img
+	for currentImg != nil {
+		if handler != nil {
+			if err := handler(currentImg); err != nil {
+				return err
+			}
+		}
+		currentImg, err = graph.GetParent(currentImg)
+		if err != nil {
+			return fmt.Errorf("Error while getting parent image: %v", err)
+		}
+	}
+	return nil
+}
+
+// depth returns the number of parents for a
+// current image
+func (graph *Graph) depth(img *image.Image) (int, error) {
+	var (
+		count  = 0
+		parent = img
+		err    error
+	)
+
+	for parent != nil {
+		count++
+		parent, err = graph.GetParent(parent)
+		if err != nil {
+			return -1, err
+		}
+	}
+	return count, nil
+}
+
+// Set the max depth to the aufs default that most
+// kernels are compiled with
+// For more information see: http://sourceforge.net/p/aufs/aufs3-standalone/ci/aufs3.12/tree/config.mk
+const MaxImageDepth = 127
+
+// CheckDepth returns an error if the depth of an image, as returned
+// by ImageDepth, is too large to support creating a container from it
+// on this daemon.
+func (graph *Graph) CheckDepth(img *image.Image) error {
+	// We add 2 layers to the depth because the container's rw and
+	// init layer add to the restriction
+	depth, err := graph.depth(img)
+	if err != nil {
+		return err
+	}
+	if depth+2 >= MaxImageDepth {
+		return fmt.Errorf("Cannot create container with more than %d parents", MaxImageDepth)
+	}
+	return nil
+}
+
 func (s *TagStore) History(name string) ([]*types.ImageHistory, error) {
 	foundImage, err := s.LookupImage(name)
 	if err != nil {
@@ -27,7 +100,7 @@ func (s *TagStore) History(name string) ([]*types.ImageHistory, error) {
 
 	history := []*types.ImageHistory{}
 
-	err = foundImage.WalkHistory(func(img *image.Image) error {
+	err = s.graph.WalkHistory(foundImage, func(img *image.Image) error {
 		history = append(history, &types.ImageHistory{
 			ID:        img.ID,
 			Created:   img.Created.Unix(),
@@ -41,3 +114,19 @@ func (s *TagStore) History(name string) ([]*types.ImageHistory, error) {
 
 	return history, err
 }
+
+func (graph *Graph) GetParent(img *image.Image) (*image.Image, error) {
+	if img.Parent == "" {
+		return nil, nil
+	}
+	return graph.Get(img.Parent)
+}
+
+func (graph *Graph) GetParentsSize(img *image.Image, size int64) int64 {
+	parentImage, err := graph.GetParent(img)
+	if err != nil || parentImage == nil {
+		return size
+	}
+	size += parentImage.Size
+	return graph.GetParentsSize(parentImage, size)
+}
diff --git a/graph/list.go b/graph/list.go
index f95508e950..f5f51f68b9 100644
--- a/graph/list.go
+++ b/graph/list.go
@@ -103,7 +103,7 @@ func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) {
 					newImage.ID = image.ID
 					newImage.Created = int(image.Created.Unix())
 					newImage.Size = int(image.Size)
-					newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size)
+					newImage.VirtualSize = int(s.graph.GetParentsSize(image, 0) + image.Size)
 					newImage.Labels = image.ContainerConfig.Labels
 
 					if utils.DigestReference(ref) {
@@ -140,7 +140,7 @@ func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) {
 			newImage.ID = image.ID
 			newImage.Created = int(image.Created.Unix())
 			newImage.Size = int(image.Size)
-			newImage.VirtualSize = int(image.GetParentsSize(0) + image.Size)
+			newImage.VirtualSize = int(s.graph.GetParentsSize(image, 0) + image.Size)
 			newImage.Labels = image.ContainerConfig.Labels
 
 			images = append(images, newImage)
diff --git a/graph/manifest_test.go b/graph/manifest_test.go
index 63086f4d55..0b8e7a2fb0 100644
--- a/graph/manifest_test.go
+++ b/graph/manifest_test.go
@@ -57,7 +57,7 @@ func (s *TagStore) newManifest(localName, remoteName, tag string) ([]byte, error
 		metadata = *layer.Config
 	}
 
-	for ; layer != nil; layer, err = layer.GetParent() {
+	for ; layer != nil; layer, err = s.graph.GetParent(layer) {
 		if err != nil {
 			return nil, err
 		}
@@ -72,12 +72,12 @@ func (s *TagStore) newManifest(localName, remoteName, tag string) ([]byte, error
 			}
 		}
 
-		checksum, err := layer.GetCheckSum(s.graph.ImageRoot(layer.ID))
+		checksum, err := s.graph.GetCheckSum(layer.ID)
 		if err != nil {
 			return nil, fmt.Errorf("Error getting image checksum: %s", err)
 		}
 		if tarsum.VersionLabelForChecksum(checksum) != tarsum.Version1.String() {
-			archive, err := layer.TarLayer()
+			archive, err := s.graph.TarLayer(layer)
 			if err != nil {
 				return nil, err
 			}
@@ -95,12 +95,12 @@ func (s *TagStore) newManifest(localName, remoteName, tag string) ([]byte, error
 			checksum = tarSum.Sum(nil)
 
 			// Save checksum value
-			if err := layer.SaveCheckSum(s.graph.ImageRoot(layer.ID), checksum); err != nil {
+			if err := s.graph.SetCheckSum(layer.ID, checksum); err != nil {
 				return nil, err
 			}
 		}
 
-		jsonData, err := layer.RawJson()
+		jsonData, err := s.graph.RawJSON(layer.ID)
 		if err != nil {
 			return nil, fmt.Errorf("Cannot retrieve the path for {%s}: %s", layer.ID, err)
 		}
@@ -141,7 +141,7 @@ func TestManifestTarsumCache(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if cs, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID)); err != nil {
+	if cs, err := store.graph.GetCheckSum(testManifestImageID); err != nil {
 		t.Fatal(err)
 	} else if cs != "" {
 		t.Fatalf("Non-empty checksum file after register")
@@ -153,7 +153,7 @@ func TestManifestTarsumCache(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	manifestChecksum, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID))
+	manifestChecksum, err := store.graph.GetCheckSum(testManifestImageID)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -175,7 +175,7 @@ func TestManifestTarsumCache(t *testing.T) {
 		t.Fatalf("Unexpected number of layer history, expecting 1: %d", len(manifest.History))
 	}
 
-	v1compat, err := img.RawJson()
+	v1compat, err := store.graph.RawJSON(img.ID)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -207,7 +207,7 @@ func TestManifestDigestCheck(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	if cs, err := img.GetCheckSum(store.graph.ImageRoot(testManifestImageID)); err != nil {
+	if cs, err := store.graph.GetCheckSum(testManifestImageID); err != nil {
 		t.Fatal(err)
 	} else if cs != "" {
 		t.Fatalf("Non-empty checksum file after register")
diff --git a/graph/push.go b/graph/push.go
index 532256fb54..24526b4507 100644
--- a/graph/push.go
+++ b/graph/push.go
@@ -5,9 +5,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
-	"path/filepath"
 	"sync"
 
 	"github.com/Sirupsen/logrus"
@@ -57,7 +55,7 @@ func (s *TagStore) getImageList(localRepo map[string]string, requestedTag string
 
 		tagsByImage[id] = append(tagsByImage[id], tag)
 
-		for img, err := s.graph.Get(id); img != nil; img, err = img.GetParent() {
+		for img, err := s.graph.Get(id); img != nil; img, err = s.graph.GetParent(img) {
 			if err != nil {
 				return nil, nil, err
 			}
@@ -248,7 +246,7 @@ func (s *TagStore) pushRepository(r *registry.Session, out io.Writer,
 
 func (s *TagStore) pushImage(r *registry.Session, out io.Writer, imgID, ep string, token []string, sf *streamformatter.StreamFormatter) (checksum string, err error) {
 	out = ioutils.NewWriteFlusher(out)
-	jsonRaw, err := ioutil.ReadFile(filepath.Join(s.graph.Root, imgID, "json"))
+	jsonRaw, err := s.graph.RawJSON(imgID)
 	if err != nil {
 		return "", fmt.Errorf("Cannot retrieve the path for {%s}: %s", imgID, err)
 	}
@@ -349,7 +347,7 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o
 
 		layersSeen := make(map[string]bool)
 		layers := []*image.Image{layer}
-		for ; layer != nil; layer, err = layer.GetParent() {
+		for ; layer != nil; layer, err = s.graph.GetParent(layer) {
 			if err != nil {
 				return err
 			}
@@ -372,12 +370,12 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o
 					return err
 				}
 			}
-			jsonData, err := layer.RawJson()
+			jsonData, err := s.graph.RawJSON(layer.ID)
 			if err != nil {
 				return fmt.Errorf("cannot retrieve the path for %s: %s", layer.ID, err)
 			}
 
-			checksum, err := layer.GetCheckSum(s.graph.ImageRoot(layer.ID))
+			checksum, err := s.graph.GetCheckSum(layer.ID)
 			if err != nil {
 				return fmt.Errorf("error getting image checksum: %s", err)
 			}
@@ -401,7 +399,7 @@ func (s *TagStore) pushV2Repository(r *registry.Session, localRepo Repository, o
 					return err
 				} else if cs != checksum {
 					// Cache new checksum
-					if err := layer.SaveCheckSum(s.graph.ImageRoot(layer.ID), cs); err != nil {
+					if err := s.graph.SetCheckSum(layer.ID, cs); err != nil {
 						return err
 					}
 					checksum = cs
@@ -456,7 +454,7 @@ func (s *TagStore) pushV2Image(r *registry.Session, img *image.Image, endpoint *
 	if err != nil {
 		return "", err
 	}
-	arch, err := image.TarLayer()
+	arch, err := s.graph.TarLayer(image)
 	if err != nil {
 		return "", err
 	}
diff --git a/graph/service.go b/graph/service.go
index 52dde1d980..7718bab769 100644
--- a/graph/service.go
+++ b/graph/service.go
@@ -14,7 +14,7 @@ func (s *TagStore) LookupRaw(name string) ([]byte, error) {
 		return nil, fmt.Errorf("No such image %s", name)
 	}
 
-	imageInspectRaw, err := image.RawJson()
+	imageInspectRaw, err := s.graph.RawJSON(image.ID)
 	if err != nil {
 		return nil, err
 	}
@@ -42,7 +42,7 @@ func (s *TagStore) Lookup(name string) (*types.ImageInspect, error) {
 		Architecture:    image.Architecture,
 		Os:              image.OS,
 		Size:            image.Size,
-		VirtualSize:     image.GetParentsSize(0) + image.Size,
+		VirtualSize:     s.graph.GetParentsSize(image, 0) + image.Size,
 	}
 
 	return imageInspect, nil
@@ -51,7 +51,7 @@ func (s *TagStore) Lookup(name string) (*types.ImageInspect, error) {
 // ImageTarLayer return the tarLayer of the image
 func (s *TagStore) ImageTarLayer(name string, dest io.Writer) error {
 	if image, err := s.LookupImage(name); err == nil && image != nil {
-		fs, err := image.TarLayer()
+		fs, err := s.graph.TarLayer(image)
 		if err != nil {
 			return err
 		}
diff --git a/image/graph.go b/image/graph.go
deleted file mode 100644
index 31fbdd9ad8..0000000000
--- a/image/graph.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package image
-
-import (
-	"github.com/docker/docker/daemon/graphdriver"
-)
-
-type Graph interface {
-	Get(id string) (*Image, error)
-	ImageRoot(id string) string
-	Driver() graphdriver.Driver
-}
diff --git a/image/image.go b/image/image.go
index 4e37ebc42d..218f18f2d7 100644
--- a/image/image.go
+++ b/image/image.go
@@ -3,22 +3,12 @@ package image
 import (
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
-	"os"
-	"path/filepath"
 	"regexp"
-	"strconv"
 	"time"
 
-	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/runconfig"
 )
 
-// Set the max depth to the aufs default that most
-// kernels are compiled with
-// For more information see: http://sourceforge.net/p/aufs/aufs3-standalone/ci/aufs3.12/tree/config.mk
-const MaxImageDepth = 127
-
 var validHex = regexp.MustCompile(`^([a-f0-9]{64})$`)
 
 type Image struct {
@@ -34,225 +24,6 @@ type Image struct {
 	Architecture    string            `json:"architecture,omitempty"`
 	OS              string            `json:"os,omitempty"`
 	Size            int64
-
-	graph Graph
-}
-
-func LoadImage(root string) (*Image, error) {
-	// Open the JSON file to decode by streaming
-	jsonSource, err := os.Open(jsonPath(root))
-	if err != nil {
-		return nil, err
-	}
-	defer jsonSource.Close()
-
-	img := &Image{}
-	dec := json.NewDecoder(jsonSource)
-
-	// Decode the JSON data
-	if err := dec.Decode(img); err != nil {
-		return nil, err
-	}
-	if err := ValidateID(img.ID); err != nil {
-		return nil, err
-	}
-
-	if buf, err := ioutil.ReadFile(filepath.Join(root, "layersize")); err != nil {
-		if !os.IsNotExist(err) {
-			return nil, err
-		}
-		// If the layersize file does not exist then set the size to a negative number
-		// because a layer size of 0 (zero) is valid
-		img.Size = -1
-	} else {
-		// Using Atoi here instead would temporarily convert the size to a machine
-		// dependent integer type, which causes images larger than 2^31 bytes to
-		// display negative sizes on 32-bit machines:
-		size, err := strconv.ParseInt(string(buf), 10, 64)
-		if err != nil {
-			return nil, err
-		}
-		img.Size = int64(size)
-	}
-
-	return img, nil
-}
-
-// StoreImage stores file system layer data for the given image to the
-// image's registered storage driver. Image metadata is stored in a file
-// at the specified root directory.
-func StoreImage(img *Image, layerData archive.ArchiveReader, root string) (err error) {
-	// Store the layer. If layerData is not nil, unpack it into the new layer
-	if layerData != nil {
-		if img.Size, err = img.graph.Driver().ApplyDiff(img.ID, img.Parent, layerData); err != nil {
-			return err
-		}
-	}
-
-	if err := img.SaveSize(root); err != nil {
-		return err
-	}
-
-	f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
-	if err != nil {
-		return err
-	}
-
-	defer f.Close()
-
-	return json.NewEncoder(f).Encode(img)
-}
-
-func (img *Image) SetGraph(graph Graph) {
-	img.graph = graph
-}
-
-// SaveSize stores the current `size` value of `img` in the directory `root`.
-func (img *Image) SaveSize(root string) error {
-	if err := ioutil.WriteFile(filepath.Join(root, "layersize"), []byte(strconv.Itoa(int(img.Size))), 0600); err != nil {
-		return fmt.Errorf("Error storing image size in %s/layersize: %s", root, err)
-	}
-	return nil
-}
-
-func (img *Image) SaveCheckSum(root, checksum string) error {
-	if err := ioutil.WriteFile(filepath.Join(root, "checksum"), []byte(checksum), 0600); err != nil {
-		return fmt.Errorf("Error storing checksum in %s/checksum: %s", root, err)
-	}
-	return nil
-}
-
-func (img *Image) GetCheckSum(root string) (string, error) {
-	cs, err := ioutil.ReadFile(filepath.Join(root, "checksum"))
-	if err != nil {
-		if os.IsNotExist(err) {
-			return "", nil
-		}
-		return "", err
-	}
-	return string(cs), err
-}
-
-func jsonPath(root string) string {
-	return filepath.Join(root, "json")
-}
-
-func (img *Image) RawJson() ([]byte, error) {
-	root, err := img.root()
-	if err != nil {
-		return nil, fmt.Errorf("Failed to get root for image %s: %s", img.ID, err)
-	}
-
-	buf, err := ioutil.ReadFile(jsonPath(root))
-	if err != nil {
-		return nil, fmt.Errorf("Failed to read json for image %s: %s", img.ID, err)
-	}
-
-	return buf, nil
-}
-
-// TarLayer returns a tar archive of the image's filesystem layer.
-func (img *Image) TarLayer() (arch archive.Archive, err error) {
-	if img.graph == nil {
-		return nil, fmt.Errorf("Can't load storage driver for unregistered image %s", img.ID)
-	}
-
-	driver := img.graph.Driver()
-
-	return driver.Diff(img.ID, img.Parent)
-}
-
-// Image includes convenience proxy functions to its graph
-// These functions will return an error if the image is not registered
-// (ie. if image.graph == nil)
-func (img *Image) History() ([]*Image, error) {
-	var parents []*Image
-	if err := img.WalkHistory(
-		func(img *Image) error {
-			parents = append(parents, img)
-			return nil
-		},
-	); err != nil {
-		return nil, err
-	}
-	return parents, nil
-}
-
-func (img *Image) WalkHistory(handler func(*Image) error) (err error) {
-	currentImg := img
-	for currentImg != nil {
-		if handler != nil {
-			if err := handler(currentImg); err != nil {
-				return err
-			}
-		}
-		currentImg, err = currentImg.GetParent()
-		if err != nil {
-			return fmt.Errorf("Error while getting parent image: %v", err)
-		}
-	}
-	return nil
-}
-
-func (img *Image) GetParent() (*Image, error) {
-	if img.Parent == "" {
-		return nil, nil
-	}
-	if img.graph == nil {
-		return nil, fmt.Errorf("Can't lookup parent of unregistered image")
-	}
-	return img.graph.Get(img.Parent)
-}
-
-func (img *Image) root() (string, error) {
-	if img.graph == nil {
-		return "", fmt.Errorf("Can't lookup root of unregistered image")
-	}
-	return img.graph.ImageRoot(img.ID), nil
-}
-
-func (img *Image) GetParentsSize(size int64) int64 {
-	parentImage, err := img.GetParent()
-	if err != nil || parentImage == nil {
-		return size
-	}
-	size += parentImage.Size
-	return parentImage.GetParentsSize(size)
-}
-
-// Depth returns the number of parents for a
-// current image
-func (img *Image) Depth() (int, error) {
-	var (
-		count  = 0
-		parent = img
-		err    error
-	)
-
-	for parent != nil {
-		count++
-		parent, err = parent.GetParent()
-		if err != nil {
-			return -1, err
-		}
-	}
-	return count, nil
-}
-
-// CheckDepth returns an error if the depth of an image, as returned
-// by ImageDepth, is too large to support creating a container from it
-// on this daemon.
-func (img *Image) CheckDepth() error {
-	// We add 2 layers to the depth because the container's rw and
-	// init layer add to the restriction
-	depth, err := img.Depth()
-	if err != nil {
-		return err
-	}
-	if depth+2 >= MaxImageDepth {
-		return fmt.Errorf("Cannot create container with more than %d parents", MaxImageDepth)
-	}
-	return nil
 }
 
 // Build an Image object from raw json data