diff --git a/apachesolr.install b/apachesolr.install
index 6f0e208..a54a359 100644
--- a/apachesolr.install
+++ b/apachesolr.install
@@ -96,12 +96,30 @@ function apachesolr_schema() {
 
   $schema['apachesolr_environment'] = array(
     'description' => 'The Solr search environment table.',
+    // Enable CTools exportables based on this table.
     'export' => array(
+      // Environment machine name.
       'key' => 'env_id',
-      'identifier' => 'name',
+      // Description of key.
+      'key name' => 'Environment machine name',
+      // Apache Solr doesn't allow disabling environments.
+      'can disable' => FALSE,
+      // Variable name to use in exported code.
+      'identifier' => 'environment',
+      // Use the environment load callback directly.
+      'load callback' => 'apachesolr_environment_load',
+      // Thin wrapper for the environment save callback.
+      'save callback' => 'apachesolr_ctools_environment_save',
+      // Thin wrapper for the environment delete callback.
+      'delete callback' => 'apachesolr_ctools_environment_delete',
+      // Includes the environment variables in 'conf' as well as the fields in this table.
+      'export callback' => 'apachesolr_ctools_environment_export',
+      // Use the same hook as the API name below.
+      'default hook' => 'apachesolr_environments',
+      // CTools API implementation.
       'api' => array(
         'owner' => 'apachesolr',
-        'api' => 'default_apachesolr_environments',
+        'api' => 'apachesolr_environments',
         'minimum_version' => 1,
         'current_version' => 1,
       ),
@@ -138,17 +156,6 @@ function apachesolr_schema() {
   );
   $schema['apachesolr_environment_variable'] = array(
     'description' => 'Variable values for each Solr search environment.',
-    'export' => array(
-      'key' => 'name',
-      'identifier' => 'name',
-      'default hook' => 'default_apachesolr_environment_variable',
-      'api' => array(
-        'owner' => 'apachesolr',
-        'api' => 'default_apachesolr_environment_variables',
-        'minimum_version' => 1,
-        'current_version' => 1,
-      ),
-    ),
     'fields' => array(
       'env_id' => array(
         'description' => 'Unique identifier for the environment',
diff --git a/apachesolr.module b/apachesolr.module
index 02720a6..c71ed95 100644
--- a/apachesolr.module
+++ b/apachesolr.module
@@ -1046,11 +1046,23 @@ function apachesolr_load_all_environments() {
   else {
     $environments = db_query('SELECT * FROM {apachesolr_environment}')->fetchAllAssoc('env_id', PDO::FETCH_ASSOC);
     foreach ($environments as $id => &$environment) {
+      $environment['conf'] = array();
       $conf = db_query('SELECT name, value FROM {apachesolr_environment_variable} WHERE env_id = :env_id', array('env_id' => $id))->fetchAllAssoc('name', PDO::FETCH_ASSOC);
       foreach ($conf as $name => $data) {
         $environment['conf'][$name] = unserialize($data['value']);
       }
     }
+
+    if (module_exists('ctools')) {
+      ctools_include('export');
+      $defaults = ctools_export_load_object('apachesolr_environment', 'all');
+      foreach ($defaults as $env_id => $default) {
+        if (!isset($environments[$env_id])) {
+          $environments[$env_id] = (array) $default;
+        }
+      }
+    }
+
     cache_set('apachesolr:environments', $environments, 'cache_apachesolr');
   }
   return $environments;
@@ -1178,7 +1190,13 @@ function apachesolr_create_unique_id($existing, $id) {
  */
 function apachesolr_environment_save($environment) {
   $default = array('env_id' => NULL, 'name' => '', 'url' => '', 'service_class' => '');
-  $is_new = !apachesolr_environment_load($environment['env_id']);
+
+  $old_environment = apachesolr_environment_load($environment['env_id']);
+  $is_new = FALSE;
+  if (!$old_environment || isset($old_environment['in_code_only'])) {
+    $is_new = TRUE;
+  }
+
   $conf = isset($environment['conf']) ? $environment['conf'] : array();
   // Remove any unexpected fields.
   // @todo - get this from the schema?.
@@ -2402,3 +2420,51 @@ function theme_apachesolr_settings_title($vars) {
 
   return $output;
 }
+
+/**
+ * Callback for saving Apache Solr environment CTools exportables.
+ *
+ * CTools uses objects, while Apache Solr uses arrays; turn CTools value into an
+ * array, then call the normal save function.
+ *
+ * @param stdclass $environment
+ *   An environment object.
+ */
+function apachesolr_ctools_environment_save($environment) {
+  apachesolr_environment_save((array) $environment);
+}
+
+/**
+ * Callback for reverting Apache Solr environment CTools exportables.
+ *
+ * @param mixed $env_id
+ *   An environment machine name. CTools may provide an id OR a complete
+ *   environment object; Since Apache Solr loads environments as arrays, this
+ *   may also be an environment array.
+ */
+function apachesolr_ctools_environment_delete($env_id) {
+  if (is_object($env_id) || is_array($env_id)) {
+    $env_id = (object) $env_id;
+    $env_id = $env_id->env_id;
+  }
+  apachesolr_environment_delete($env_id);
+}
+
+/**
+ * Callback for exporting Apache Solr environments as CTools exportables.
+ *
+ * @param array $environment
+ *   An environment array from Apache Solr.
+ * @param string $indent
+ *   White space for indentation from CTools.
+ */
+function apachesolr_ctools_environment_export($environment, $indent) {
+  ctools_include('export');
+  $environment = (object) $environment;
+  // Re-load the enviroment, since in some cases the conf
+  // is stripped since it's not in the actual schema.
+  $environment = (object) apachesolr_environment_load($environment->env_id);
+  $additions_top = array();
+  $additions_bottom = array('conf' => $environment->conf);
+  return ctools_export_object('apachesolr_environment', $environment, $indent, NULL, $additions_top, $additions_bottom);
+}
