Index: i18nsync.module
===================================================================
--- i18nsync.module	(revision 3242)
+++ i18nsync.module	(working copy)
@@ -150,6 +150,7 @@
  */
 function i18nsync_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
   global $i18nsync; // This variable will be true when a sync operation is in progress.
+  static $i18nsync_old_node = NULL;
 
   // Only for nodes that have language and belong to a translation set.
   if (translation_supported_type($node->type) && !empty($node->language) && !$i18nsync) {
@@ -198,28 +199,74 @@
         }
         // Intentional no break.
       case 'update':    
-        // Let's go with field synchronization.
-        if (!empty($node->tnid) && ($fields = i18nsync_node_fields($node->type)) && ($translations = _i18nsync_node_translations($node, TRUE))) {
-          $i18nsync = TRUE;
-          $count = 0;
-          // If we have fields we need to reload them so we have the full data (fid, etc...)
-          if (!empty($node->files) && in_array('files', $fields)) {
-            $node->files = upload_load($node);
-          }
-          // Disable language selection temporarily, enable it again later
-          i18n_selection_mode('off');
-          foreach ($translations as $trnode) {
-            if ($node->nid != $trnode->nid) {
-              i18nsync_node_translation($node, $trnode, $fields, $op);
-              $count++;
+        // Process field synchronization, but check first if it's necessary. 
+        // We have the previous state of the node object stored in $i18nsync_old_node.
+        if ($i18nsync_old_node && !empty($node->tnid) && ($fields = i18nsync_node_fields($node->type)) && ($translations = _i18nsync_node_translations($node, TRUE))) {
+          $i18nsync = FALSE; // no synchronization yet
+          // load a fresh node object as it might contain a lot of form validation junk, e. g. "_error_element",
+          // making a field compare impossible.
+          $node = node_load($node->nid, $node->vid); 
+          foreach ($fields as $field) {
+            switch ($field) {
+              case 'files':
+                // Check whether to sync existing attached files.
+                if (count((array)$node->files) == count((array)$old_node->files)) {
+                  foreach ((array)$node->files as $fid => $file) {
+                    if (!isset($i18nsync_old_node->files[$fid]) || !empty($file->remove)) {
+                      $i18nsync = TRUE;
+                      break;
+                    }
+                  }
+                }
+                else {
+                  $i18nsync = TRUE;
+                }
+                break;
+   
+              default:
+                // For fields that don't need special handling.
+                if (isset($node->$field)) {
+                  if ($node->$field != $i18nsync_old_node->$field) {
+                    $i18nsync = TRUE;
+                  }
+                }
             }
+          }         
+          
+          if ($i18nsync) {  
+            $count = 0;
+            // If we have fields we need to reload them so we have the full data (fid, etc...)
+            if (!empty($node->files) && in_array('files', $fields)) {
+              $node->files = upload_load($node);
+            }
+            // Disable language selection temporarily, enable it again later
+            i18n_selection_mode('off');
+            foreach ($translations as $trnode) {
+              if ($node->nid != $trnode->nid) {
+                i18nsync_node_translation($node, $trnode, $fields, $op);
+                $count++;
+              }
+            }
+            i18n_selection_mode('reset');
+            $i18nsync = FALSE;
+            $i18nsync_old_node = NULL; // remove old node object
+            drupal_set_message(format_plural($count, 'One node translation has been synchronized.', 'All @count node translations have been synchronized.'));
           }
-          i18n_selection_mode('reset');
-          $i18nsync = FALSE;
-          drupal_set_message(format_plural($count, 'One node translation has been synchronized.', 'All @count node translations have been synchronized.'));
         }
         break;
-    }
+      
+      case 'presave':
+         // Takes a snapshot of the node's state. We need this information for comparing the node's fields
+         // before and after saving it. Then we can recognize a difference and decide whether a synchronziation is necessary.      
+         if (!empty($node->tnid) && ($fields = i18nsync_node_fields($node->type)) && ($translations = translation_node_get_translations($node->tnid)) && count($translations) > 1) {
+           if (isset($node->nid) && isset($node->vid)) { // take a node object snapshot
+             $i18nsync_old_node = node_load($node->nid, $node->vid);
+           }
+         }
+         break;
+    }   
+       
+     
   }
 }
 
