Index: image.admin.inc
===================================================================
--- image.admin.inc	(revision 250)
+++ image.admin.inc	(working copy)
@@ -23,6 +23,21 @@
     '#description' => t('Subdirectory in the directory %dir where pictures will be stored. Do not include trailing slash.', array('%dir' => file_directory_path())),
   );
 
+  // If token module is installed, show the possible replacement patterns for the filepath.
+  if (module_exists('token')) {
+    $form['files']['token_help'] = array(
+      '#title' => t('Replacement patterns'),
+      '#type' => 'fieldset',
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#description' => t('Prefer raw-text replacements for text to avoid problems with HTML entities!'),
+    );
+
+    $form['files']['token_help']['help'] = array(
+      '#value' => theme('token_help', 'node'), // global tokens only, we don't have a node yet
+    );
+  }
+
   $form['files']['image_max_upload_size'] = array(
     '#type' => 'textfield',
     '#title' => t('Maximum upload size'),
Index: image.module
===================================================================
--- image.module	(revision 250)
+++ image.module	(working copy)
@@ -138,7 +138,7 @@
  * Implements hook_cron. (deletes old temp images)
  */
 function image_cron() {
-  $path = file_directory_path() .'/'. variable_get('image_default_path', 'images') .'/temp';
+  $path = file_directory_path() .'/'. _image_strip_tokens_from_path(variable_get('image_default_path', 'images')) .'/temp';
   $files = file_scan_directory(file_create_path($path), '.*');
   foreach ($files as $file => $info) {
     if (time() - filemtime($file) > 60*60*6) {
@@ -377,7 +377,7 @@
 
   // New image uploads need to be saved in images/temp in order to be viewable
   // during node preview.
-  $temporary_file_path = file_create_path(file_directory_path() . '/' . variable_get('image_default_path', 'images') .'/temp');
+  $temporary_file_path = file_create_path(file_directory_path() . '/' . _image_strip_tokens_from_path(variable_get('image_default_path', 'images')) .'/temp');
 
   if ($file = file_save_upload('image', $validators, $temporary_file_path)) {
     // Resize the original.
@@ -753,7 +753,7 @@
  */
 function _image_check_settings() {
   // File paths
-  $image_path = file_create_path(file_directory_path() .'/'. variable_get('image_default_path', 'images'));
+  $image_path = file_create_path(file_directory_path() .'/'. _image_strip_tokens_from_path(variable_get('image_default_path', 'images')));
   $temp_path = $image_path .'/temp';
 
   if (!file_check_directory($image_path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS, 'image_default_path')) {
@@ -864,11 +864,26 @@
 /**
  * Creates an image filename.
  */
-function _image_filename($filename, $label = IMAGE_ORIGINAL, $temp = FALSE) {
-  $path = file_directory_path() .'/'. variable_get('image_default_path', 'images');
+function _image_filename($filename, $label = IMAGE_ORIGINAL, $temp = FALSE, $node = NULL) {
+  $file_directory_path = file_directory_path();
+  $file_path_pattern = variable_get('image_default_path', 'images');
   if ($temp) {
-    $path .= '/temp';
+    $path = $file_directory_path . '/' . _image_strip_tokens_from_path($file_path_pattern) . '/temp';
   }
+  elseif(module_exists('token') && $node) { // Support tokens for final destination if node and the token module are available
+    // Create path to image file using tokens
+    $relpath = token_replace($file_path_pattern . '/', 'node', $node);
+    // Make sure target directory exists
+    $dirs = explode('/', $relpath);
+    $path = $file_directory_path;
+    while (count($dirs)) {
+      $path .= '/' . array_shift($dirs);
+      file_check_directory($path, FILE_CREATE_DIRECTORY);
+    }
+  }
+  else {
+    $path = $file_directory_path . '/' . $file_path_pattern;
+  }
 
   $filename = basename($filename);
 
@@ -890,6 +905,19 @@
 }
 
 /**
+ * Strips tokens from path
+ */
+function _image_strip_tokens_from_path($path) {
+  if (module_exists('token')) {
+    $tmp_path = preg_replace('/\[.+\]/', '', $path);
+    return preg_replace('/\/+/', '/', $tmp_path);
+  }
+  else {
+    return $path;
+  }
+}
+
+/**
  * Helper function to return the defined sizes (or proper defaults).
  *
  * @param $size
@@ -963,7 +991,7 @@
  */
 function _image_insert(&$node, $size, $image_path) {
   $original_path = $node->images[IMAGE_ORIGINAL];
-  if (file_move($image_path, _image_filename($original_path, $size))) {
+  if (file_move($image_path, _image_filename($original_path, $size, FALSE, $node))) {
     // Update the node to reflect the actual filename, it may have been changed
     // if a file of the same name already existed.
     $node->images[$size] = $image_path;
Index: image.install
===================================================================
--- image.install	(revision 250)
+++ image.install	(working copy)
@@ -84,7 +84,7 @@
 
 
     // File paths
-    $image_path = file_create_path(file_directory_path() .'/'. variable_get('image_default_path', 'images'));
+    $image_path = file_create_path(file_directory_path() .'/'. _image_strip_tokens_from_path(variable_get('image_default_path', 'images')));
     $temp_path = $image_path . '/temp';
     if (!file_check_directory($image_path, FILE_CREATE_DIRECTORY)) {
       $requirements['image_dirs'] = array(
