diff -ruN node_import/import_flexinode.inc node_import/import_flexinode.inc
--- node_import/import_flexinode.inc	2005-07-01 22:07:08.000000000 -0400
+++ node_import/import_flexinode.inc	2006-02-23 11:10:58.000000000 -0500
@@ -32,14 +32,6 @@
   }
 }
 
-function flexinode_node_import_global($type) {
-  $type = explode('-', $type);
-
-  if ($type[0] == 'flexinode') {
-    return implode('', taxonomy_node_form('flexinode-'. $type[1]));
-  }
-}
-
 function flexinode_node_import_prepare(&$node, $preview = FALSE) {
   $type = explode('-', $node->type);
 
@@ -58,6 +50,7 @@
           $node->{'flexinode_'. $field->field_id .'hour'} = $time['hours'];
           $node->{'flexinode_'. $field->field_id .'minute'} = $time['minutes'];
         }
+        // Hmm.
         unset($node->$whatdate);
       }
     }
diff -ruN node_import/import_taxonomy.inc node_import/import_taxonomy.inc
--- node_import/import_taxonomy.inc	1969-12-31 19:00:00.000000000 -0500
+++ node_import/import_taxonomy.inc	2006-02-23 11:20:54.000000000 -0500
@@ -0,0 +1,30 @@
+<?php
+/* $Id$ */
+
+function taxonomy_node_import_global($type) {
+  $node->type = $type;
+  $form['type']['#value'] = $node->type;
+  $form['#node']->type = $node->type;
+
+  taxonomy_form_alter($node->type .'_node_form', $form);
+  unset($form['#node']);
+  unset($form['type']);
+  return $form;
+}
+
+function taxonomy_node_import_prepare(&$node, $preview = FALSE) {
+   //
+   // This function needs to populate the $node object with taxonomy data in preparation for node_save(). 
+   //
+   // $node->taxonomy[] = array('term 1', 'term 2');
+   //
+   // The data structure is different for free-tagging vocabularies.
+   // $node->taxonomy['tags'][vid] = array('tag 1', 'tag 2');
+   //
+   //  That is, at least, my interpretation of taxonomy_node_save().  I have not verified this structure.
+   //  
+   //  Nic Ivy (njivy)
+   //
+
+}
+?>
diff -ruN node_import/node_import.module node_import/node_import.module
--- node_import/node_import.module	2005-06-27 22:16:34.000000000 -0400
+++ node_import/node_import.module	2006-02-23 11:23:31.000000000 -0500
@@ -42,7 +42,11 @@
 function node_import_menu($may_cache) {
   $links = array();
   if ($may_cache) {
-    $links[] = array('path' => 'admin/node/node_import', 'title' => t('import'), 'callback' => 'node_import_page', 'weight' => 5, 'access' => user_access('import nodes'));
+    $links[] = array('path' => 'admin/node/node_import', 
+                     'title' => t('import'), 
+                     'callback' => 'node_import_page', 
+                     'weight' => 5, 
+                     'access' => user_access('import nodes'));
   }
   return $links;
 }
@@ -54,8 +58,12 @@
 function node_import_page() {
   $edit = array_merge($_SESSION['node_import'], $_POST['edit']);
 
+  // This prevents drupal_get_form() from performing extra validation.
+  unset($_POST['edit']);
+
   // validate the form
   if ($_SESSION['node_import_page'] && $_POST) {
+    // Hmm.
     $function = $_SESSION['node_import_page'] .'_validate';
     $function($_POST['op'], $edit);
   }
@@ -69,29 +77,52 @@
   $_SESSION['node_import'] = $edit;
   
   if ($_POST['op'] == t('Download rows with errors')) {
-    print $output;
+    return $output;
   }
   else {
-    print theme('page', $output);
+    return $output;
   }
 }
 
 function _node_import_start($edit) {
   if ($edit['file']) {
-    $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .')<br />'. form_submit(t('Use a different file')));
+    $form[] = array(
+      '#type' => 'item',
+      '#title' => t('File'),
+      '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .')'
+    );
+    $form[] = array(
+      '#type' => 'submit',
+      '#value' => t('Use a different file')
+    );
   }
   else {
-    $output .= form_file(t('Upload CSV file'), 'file', 48, t('Comma separated values file containing the data to be imported.'));
+    $form['file'] = array(
+      '#type' => 'file',
+      '#title' => t('Upload CSV file'),
+      '#size' => 48,
+      '#description' => t('Comma separated values file containing the data to be imported.'),
+    );
   }
   
   $types = module_invoke_all('node_import_types');
   $types['node_import'] = t('raw data (advanced)');
-  $output .= form_select(t('Type'), 'type', $edit['type'], $types);
-
+  $form['type'] = array(
+    '#type' => 'select',
+    '#title' => t('Type'),
+    '#default_value' => $edit['type'],
+    '#options' => $types,
+  );
   // todo add an insert/update option
 
-  $output .= form_submit(t('Next'));
-  return form($output, 'post', 0, array('enctype' => 'multipart/form-data'));
+  $form[] = array(
+    '#type' => 'submit',
+    '#value' => t('Next'),
+  );
+  $form['#method'] = 'post';
+  $form['#action'] = 0;
+  $form['#attributes'] = array('enctype' => 'multipart/form-data');
+  return drupal_get_form('node_import_start', $form);
 }
 
 function _node_import_start_validate($op, &$edit) {
@@ -129,12 +160,20 @@
 }
 
 function _node_import_options($edit) {
-  $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ');
+  $form[] = array(
+    '#type' => 'item',
+    '#title' => t('File'),
+    '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ',
+  );
 
   // todo add in a place to select fields to match on for update
 
   if ($edit['type'] != 'node_import') {
-    $output .= '<h3>'. t('Field matching') .'</h3>';
+    $form[] = array(
+      '#type' => 'item',
+      '#title' => t('Field matching'),
+      '#value' => ''
+    );
     $fields = array_merge(array('' => t('<none>')), module_invoke_all('node_import_fields', $edit['type']));
     $header = array(t('CSV header'), t('Import to field'), t('Sample data'));
     $data = array();
@@ -146,7 +185,14 @@
       }
     }
     foreach ($csvheader as $i => $value) {
-      $data[] = array($value, form_select('', 'match]['. $i, $edit['match'][$i], $fields));
+      $form['match]['. $i] = array(
+        '#type' => 'select',
+        '#title' => '',
+        '#default_value' => $edit['match'][$i],
+        '#options' => $fields
+      );
+      $form = form_builder('node_import_options', $form);
+      $data[] = array($value, form_render($form['match]['. $i]));
     }
     $j = 0;
     while (($row = fgetcsv($handle, 10000, ',')) && $j++ < 5) {
@@ -158,16 +204,31 @@
     foreach ($datatmp as $i => $value) {
       $data[$i][] = implode(', ', $value);
     }
-    $output .= theme('table', $header, $data);
 
-    if ($global = implode('', module_invoke_all('node_import_global', $edit['type']))) {
-      $output .= form_group(t('Global fields'), str_replace('edit[', 'edit[global][', $global));
+    $form[] = array(
+      '#type' => 'item',
+      '#title' => '',
+      '#value' => theme('table', $header, $data)
+    );
+
+    if ($global = module_invoke_all('node_import_global', $edit['type'])) {
+      $form['global'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Global fields'),
+      );
+      $form['global'] = $global;
     }
   }
 
-  $output .= form_submit(t('Preview'));
-  $output .= form_submit(t('Back'));
-  return form($output);
+  $form[] = array(
+    '#type' => 'submit',
+    '#value' => t('Preview'),
+  );
+  $form[] = array(
+    '#type' => 'submit',
+    '#value' => t('Back'),
+  );
+  return drupal_get_form('node_import_opts', $form);
 }
 
 function _node_import_options_validate($op, &$edit) {
@@ -180,22 +241,45 @@
 }
 
 function _node_import_preview($edit) {
-  $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ');
-
-  $output .= '<h3>'. t('Preview') .'</h3>';
-  $output .= form_select(t('Number of entries'), 'preview_count', $edit['preview_count'], drupal_map_assoc(array(5, 10, 15, 25, 50, 100, 150, 200)));
+  $form[] = array(
+    '#type' => 'item',
+    '#title' => 'Preview',
+    '#value' => '<p>'. t('Importing may take awhile, do not click \'Import\' more than once. To see progress, look at the Administer >> Content page in a new window.') .'</p>'
+  );
+  $form[] = array(
+    '#type' => 'item',
+    '#title' => t('File'),
+    '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ',
+  );
   if (!$edit['preview_count']) {
     $edit['preview_count'] = 5;
   }
-  $output .= form_submit(t('Apply'));
-  
-  $output .= _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global'], $edit['preview_count']);
 
-  $output .= '<p>'. t('Importing may take awhile, do not click \'Import\' more than once. To see progress, look at the Administer >> Content page in a new window.') .'</p>';
-
-  $output .= form_submit(t('Import'));
-  $output .= form_submit(t('Back'));
-  return form($output);
+  $form[] = array(
+    '#type' => 'item',
+    '#title' => '',
+    '#value' => _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global'], $edit['preview_count'])
+  );
+
+  $form['preview_count'] = array(
+    '#type' => 'select',
+    '#title' => t('Number of entries to preview'),
+    '#default_value' => $edit['preview_count'],
+    '#options' => drupal_map_assoc(array(5, 10, 15, 25, 50, 100, 150, 200)),
+  );
+  $form[] = array(
+    '#type' => 'submit',
+    '#value' => t('Apply'),
+  );
+  $form[] = array(
+    '#type' => 'submit',
+    '#value' => t('Import'),
+  );
+  $form[] = array(
+    '#type' => 'submit',
+    '#value' => t('Back'),
+  );
+  return drupal_get_form('_node_import_prev', $form);
 }
 
 function _node_import_preview_validate($op, &$edit) {
@@ -210,17 +294,31 @@
   else if ($op == t('Import')) {
     $_SESSION['node_import_page'] = '_node_import_import';
   }
+  else if ($op == t('Apply')) {
+    $_SESSION['node_import_page'] = '_node_import_preview';
+  }
 }
 
 function _node_import_import(&$edit) {
-  $output .= form_item(t('File'), $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ');
-  $output .= form_submit(t('Delete CSV file from server')); 
+  $form[] = array(
+    '#type' => 'item',
+    '#title' => t('File'),
+    '#value' => $edit['filename'] .' ('. format_size($edit['file']->filesize) .') ',
+  );
+  $form[] = array(
+    '#type' => 'submit',
+    '#value' => t('Delete CSV file from server'),
+  );
 
   $edit['errors'] = 0;
-  $output .= _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global'], $edit['errors']);
+  $form[] = array(
+    '#type' => 'item',
+    '#title' => '',
+    '#value' => _node_import_get_nodes($edit['file']->filepath, $edit['type'], $edit['type'] == 'node_import' ? NULL : $edit['match'], $edit['global'], $edit['errors'])
+  );
   unset($edit['match']);
 
-  return form($output);
+  return drupal_get_form('node_import_import', $form);
 }
 
 function _node_import_import_validate($op, &$edit) {
@@ -252,6 +350,7 @@
 }
 
 function _node_import_get_nodes($path, $type, $match, $global, &$preview) {
+  $preview = TRUE;
   $handle = fopen($path, 'r');
   $header = fgetcsv($handle, 10000, ',');
   if (!$match) {
@@ -263,9 +362,9 @@
   $j = 0;
   $success = 0;
   while (($row = fgetcsv($handle, 10000, ',')) && ($j++ < $preview || $preview == 0)) {
-    $node = array2object(array_merge(array('type' => $type), module_invoke_all('node_import_static', $type), $global));
+    $node = (object) array_merge(array('type' => $type), module_invoke_all('node_import_static', $type), $global);
     foreach ($row as $i => $value) {
-      $node->$match[$i] = $value;
+      !empty($match[$i]) && $node->$match[$i] = $value;
       if ($match[$i] == 'name') {
         if ($account = user_load(array('name' => $value))) {
           $node->uid = $account->uid;
@@ -286,7 +385,7 @@
       }
     }
 
-    $node = node_validate($node);
+    node_validate($node);
 
     if (!node_access('create', $node)) {
       drupal_set_message(t('You are not authorized to post this type of node.'), 'error'); // todo be more specific about what type
@@ -325,5 +424,4 @@
   
   return $output;
 }
-
 ?>
