]> git.saurik.com Git - apple/configd.git/blobdiff - SystemConfiguration.fproj/SCNetworkMigration.c
configd-699.1.5.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkMigration.c
diff --git a/SystemConfiguration.fproj/SCNetworkMigration.c b/SystemConfiguration.fproj/SCNetworkMigration.c
new file mode 100644 (file)
index 0000000..b56c246
--- /dev/null
@@ -0,0 +1,3683 @@
+/*
+ * Copyright (c) 2014 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+//  SCNetworkMigration.c
+//
+//  Created by Ashish Kulkarni on 11/19/13.
+//
+//
+
+#include <stdio.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCNetworkConfigurationPrivate.h>
+#include <SystemConfiguration/SCNetworkConfigurationInternal.h>
+#include "SCPreferencesInternal.h"
+#include <IOKit/network/IONetworkInterface.h>
+#include <IOKit/network/IONetworkController.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <sys/stat.h>
+#include <copyfile.h>
+#include <sys/param.h>
+#include <pthread.h>
+
+#define BACK_TO_MY_MAC                 CFSTR("BackToMyMac")
+#define BACK_TO_MY_MAC_DSIDS           CFSTR("BackToMyMacDSIDs")
+#define        PREFS_DEFAULT_DIR_PLIST         "/Library/Preferences/SystemConfiguration"
+#define PREFS_DEFAULT_DIR_RELATIVE     CFSTR("Library/Preferences/SystemConfiguration/")
+#define        PREFS_DEFAULT_CONFIG_PLIST      "preferences.plist"
+#define        NETWORK_INTERFACES_PREFS_PLIST  "NetworkInterfaces.plist"
+#define NUM_MIGRATION_PATHS            2
+#define PLUGIN_ID                      CFSTR("System Migration")
+#define PREFERENCES_PLIST_INDEX                0
+#define NETWORK_INTERFACES_PLIST_INDEX 1
+
+
+const CFStringRef kSCNetworkConfigurationMigrationActionKey = CFSTR("MigrationActionKey");
+const CFStringRef kSCNetworkConfigurationRepair = CFSTR("ConfigurationRepair");
+#if    !TARGET_OS_IPHONE
+static CFDictionaryRef
+_SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs);
+
+static CFDictionaryRef
+_SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs);
+
+static CFDictionaryRef
+_SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs);
+#endif
+static Boolean
+_SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1, SCNetworkInterfaceRef interface2, Boolean bypassActive);
+
+static Boolean
+_SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetDir);
+
+static void
+_SCNetworkConfigurationCopyMigrationPathsWithBaseURL(CFURLRef baseURL, CFURLRef *prefs, CFURLRef *interfaces)
+{
+       if (baseURL != NULL) {
+               CFRetain(baseURL);
+       }
+       else {
+               baseURL = CFURLCreateFromFileSystemRepresentation(NULL,
+                                                                 (UInt8*)PREFS_DEFAULT_DIR_PLIST,
+                                                                 sizeof(PREFS_DEFAULT_DIR_PLIST),
+                                                                 TRUE);
+       }
+
+       *prefs = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                     (UInt8*)PREFS_DEFAULT_CONFIG_PLIST,
+                                                                     sizeof(PREFS_DEFAULT_CONFIG_PLIST) - 1,
+                                                                     FALSE, baseURL);
+
+       *interfaces = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL,
+                                                                          (UInt8*)NETWORK_INTERFACES_PREFS_PLIST,
+                                                                          sizeof(NETWORK_INTERFACES_PREFS_PLIST) - 1,
+                                                                          FALSE, baseURL);
+       CFRelease(baseURL);
+       return;
+}
+
+CFArrayRef
+_SCNetworkConfigurationCopyMigrationPaths(CFDictionaryRef options)
+{
+       CFURLRef interfaces;
+       CFMutableArrayRef migrationPaths = NULL;
+       CFURLRef prefs;
+       
+       if (getenv(INSTALL_ENVIRONMENT) != NULL) {
+               _sc_debug = 1;
+       }
+       _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(NULL, &prefs, &interfaces);
+
+       migrationPaths = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       CFArrayInsertValueAtIndex(migrationPaths, PREFERENCES_PLIST_INDEX, prefs);
+       CFArrayInsertValueAtIndex(migrationPaths, NETWORK_INTERFACES_PLIST_INDEX, interfaces);
+
+       CFRelease(prefs);
+       CFRelease(interfaces);
+       return migrationPaths;
+}
+
+static Boolean
+_SCNetworkConfigurationRemoveConfigurationFiles(CFURLRef configDir)
+{
+       
+       char configPathString[PATH_MAX];
+       CFURLRef configPathURL = NULL;
+       char configNetworkInterfacesPathString[PATH_MAX];
+       CFURLRef configNetworkInterfacesPathURL = NULL;
+       
+       _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(configDir, &configPathURL, &configNetworkInterfacesPathURL);
+       
+       if(CFURLGetFileSystemRepresentation(configPathURL, TRUE, (UInt8*)configPathString, sizeof(configPathString)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: configPathString is NULL"));
+       }
+       else {
+               if (remove(configPathString) != 0) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: Removing file failed from: %s. Error is %d"), configPathString, errno);
+               }
+       }
+       
+       if(CFURLGetFileSystemRepresentation(configNetworkInterfacesPathURL, TRUE, (UInt8*)configNetworkInterfacesPathString, sizeof(configNetworkInterfacesPathString)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: configNetwork"));
+       }
+       else {
+               if (remove(configNetworkInterfacesPathString) != 0) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationRemoveConfigurationFiles: Removing file failed from: %s. Error is %d"), configNetworkInterfacesPathString, errno);
+               }
+       }
+       
+       if (configPathURL != NULL) {
+               CFRelease(configPathURL);
+       }
+       if (configNetworkInterfacesPathURL != NULL) {
+               CFRelease(configNetworkInterfacesPathURL);
+       }
+       
+       return TRUE;
+}
+
+static Boolean
+SCNetworkConfigurationCopyConfigurationFiles(CFURLRef  configDir,
+                                            CFURLRef   targetDir)      // TargetDir needs to exist
+{
+       errno_t error;
+       mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
+       char networkInterfacesPathString[PATH_MAX];
+       CFURLRef networkInterfacesPathURL = NULL;
+       copyfile_state_t networkInterfacesState;
+       char preferencesPathString[PATH_MAX];
+       CFURLRef preferencesPathURL = NULL;
+       Boolean removeTargetFiles = FALSE;
+       copyfile_state_t state;
+       Boolean success = FALSE;
+       char targetNetworkInterfacesPathString[PATH_MAX];
+       CFURLRef targetNetworkInterfacesPathURL = NULL;
+       char targetPathString[PATH_MAX];
+       CFURLRef targetPathURL = NULL;
+
+       _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(targetDir, &targetPathURL, &targetNetworkInterfacesPathURL);
+       
+       if (CFURLGetFileSystemRepresentation(targetPathURL, TRUE, (UInt8*)targetPathString, sizeof(targetPathString)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: targetPathString is NULL"));
+               goto done;
+       }
+       
+       if (CFURLGetFileSystemRepresentation(targetNetworkInterfacesPathURL, TRUE, (UInt8*)targetNetworkInterfacesPathString, sizeof(targetNetworkInterfacesPathString)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: targetNetworkInterfacesPathString is NULL"));
+               goto done;
+       }
+       
+       if (configDir == NULL) {
+               removeTargetFiles = TRUE;
+               success = TRUE;
+               goto done;
+       }
+       _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(configDir, &preferencesPathURL, &networkInterfacesPathURL);
+
+       if (CFURLGetFileSystemRepresentation(preferencesPathURL, TRUE, (UInt8*)preferencesPathString, sizeof(preferencesPathString)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: preferencesPathString is NULL"));
+               goto done;
+       }
+
+
+       if (CFURLGetFileSystemRepresentation(networkInterfacesPathURL, TRUE, (UInt8*)networkInterfacesPathString, sizeof(networkInterfacesPathString)) == FALSE) {
+               SCLog(_sc_debug, LOG_DEBUG, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: networkInterfacePathString is NULL"));
+               goto done;
+       }
+       
+       state = copyfile_state_alloc();
+       if ((error = copyfile(preferencesPathString, targetPathString, state, COPYFILE_ALL)) != 0) {
+               SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: Copying failed from:%s to %s. Error is %d"), preferencesPathString, targetPathString, errno);
+               copyfile_state_free(state);
+               removeTargetFiles = TRUE;
+               goto done;
+       }
+       copyfile_state_free(state);
+       chmod(targetPathString, mode);
+
+       networkInterfacesState = copyfile_state_alloc();
+       if ((error = copyfile(networkInterfacesPathString, targetNetworkInterfacesPathString, networkInterfacesState, COPYFILE_ALL)) != 0) {
+               SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConfigurationCopyConfigurationFiles: Copying failed from:%s to %s. Error is %d"), networkInterfacesPathString, targetNetworkInterfacesPathString, errno);
+               copyfile_state_free(networkInterfacesState);
+               removeTargetFiles = TRUE;
+               goto done;
+       }
+       copyfile_state_free(networkInterfacesState);
+       chmod(targetNetworkInterfacesPathString, mode);
+
+       success = TRUE;
+done:
+       if (removeTargetFiles == TRUE) {
+               _SCNetworkConfigurationRemoveConfigurationFiles(targetDir);
+       }
+       if (preferencesPathURL != NULL) {
+               CFRelease(preferencesPathURL);
+       }
+       if (networkInterfacesPathURL != NULL) {
+               CFRelease(networkInterfacesPathURL);
+       }
+       if (targetPathURL != NULL) {
+               CFRelease(targetPathURL);
+       }
+       if (targetNetworkInterfacesPathURL != NULL) {
+               CFRelease(targetNetworkInterfacesPathURL);
+       }
+       return success;
+}
+
+
+/* -----------------------------------------------------------------------------
+ Create directories and intermediate directories as required.
+ ----------------------------------------------------------------------------- */
+static Boolean
+_SCNetworkConfigurationMakePathIfNeeded(CFURLRef pathURL)
+{
+       char    *c;
+       mode_t  newmask;
+       char    path[PATH_MAX];
+       char    thepath[PATH_MAX];
+       CFIndex slen=0;
+       struct stat sb;
+       Boolean success = FALSE;
+
+       if (CFURLGetFileSystemRepresentation(pathURL, TRUE, (UInt8 *)path, sizeof(path)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMakePathIfNeeded: Could not get character array from target string"));
+               return success;
+       }
+       SCLog(TRUE, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMakePathIfNeeded: Creating path: %s"), path);
+       
+       newmask = S_IRWXU | S_IRGRP | S_IROTH | S_IXGRP | S_IXOTH;
+
+       slen = strlen(path);
+
+       strlcpy( thepath, path, slen+1);
+       c = thepath;
+       if ( *c == '/' )
+               c++;
+       for(  ; !success; c++){
+               if ( (*c == '/') || ( *c == '\0' )){
+                       if ( *c == '\0' )
+                               success = TRUE;
+                       else
+                               *c = '\0';
+                       if ( mkdir( thepath, newmask) ){
+                               if ( errno == EEXIST || errno == EISDIR){
+                                       if ( stat(thepath, &sb) < 0){
+                                               printf("stat returned value < 0\n");
+                                               break;
+                                       }
+                               } else {
+                                       printf("received error: %s\n", strerror(errno));
+                                       break;
+                               }
+                       }
+                       *c = '/';
+               }
+       }
+       return success;
+}
+
+static SCPreferencesRef
+__SCNetworkCreateDefaultPref(CFStringRef prefsID)
+{
+       SCPreferencesRef prefs;
+       SCNetworkSetRef currentSet;
+       CFStringRef model;
+       
+       prefs = SCPreferencesCreate(NULL, PLUGIN_ID, prefsID);
+       if (prefs == NULL) {
+               return NULL;
+       }
+       
+       currentSet = SCNetworkSetCopyCurrent(prefs);
+       if (currentSet == NULL) {
+               CFBundleRef bundle;
+               CFStringRef setName = NULL;
+               
+               currentSet = SCNetworkSetCreate(prefs);
+               bundle = _SC_CFBundleGet();
+               if (bundle != NULL) {
+                       setName = CFBundleCopyLocalizedString(bundle,
+                                                             CFSTR("DEFAULT_SET_NAME"),
+                                                             CFSTR("Automatic"),
+                                                             NULL);
+               }
+               SCNetworkSetSetName(currentSet, (setName != NULL) ? setName : CFSTR("Automatic"));
+               SCNetworkSetSetCurrent(currentSet);
+               if (setName != NULL) {
+                       CFRelease(setName);
+               }
+       }
+       SCNetworkSetEstablishDefaultConfiguration(currentSet);
+       CFRelease(currentSet);
+       
+       model = SCPreferencesGetValue(prefs, MODEL);
+       if (model == NULL) {
+               model = _SC_hw_model(FALSE);
+               SCPreferencesSetValue(prefs, MODEL, model);
+       }
+       
+       return prefs;
+}
+
+__private_extern__
+SCPreferencesRef
+__SCNetworkCreateDefaultNIPrefs(CFStringRef prefsID)
+{
+       CFMutableArrayRef interfaces = NULL;
+       CFStringRef model;
+       CFArrayRef networkInterfaces;
+       SCPreferencesRef ni_prefs;
+       CFComparisonResult res;
+       
+       
+       networkInterfaces = __SCNetworkInterfaceCopyAll_IONetworkInterface();
+       
+       if (networkInterfaces == NULL) {
+               return NULL;
+       }
+       if (prefsID == NULL) {
+               prefsID = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@/%@"), PREFS_DEFAULT_DIR, NETWORK_INTERFACES_PREFS);
+       }
+       else {
+               CFRetain(prefsID);
+       }
+       
+       ni_prefs = SCPreferencesCreate(NULL, PLUGIN_ID , prefsID);
+       CFRelease(prefsID);
+       
+       if (ni_prefs == NULL) {
+               goto done;
+       }
+       
+       interfaces = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(networkInterfaces); idx++) {
+               CFIndex idx2 = 0;
+               CFNumberRef if_type;
+               CFNumberRef if_unit;
+               SCNetworkInterfaceRef interface = CFArrayGetValueAtIndex(networkInterfaces, idx);
+               CFDictionaryRef interfaceEntity = __SCNetworkInterfaceCopyStorageEntity(interface);
+               
+               if (interfaceEntity == NULL) {
+                       continue;
+               }
+               
+               if_type = _SCNetworkInterfaceGetIOInterfaceType(interface);
+               if_unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
+               
+               if ((if_type == NULL) || (if_unit == NULL)) {
+                       CFRelease(interfaceEntity);
+                       continue;
+               }
+               
+               for (idx2 = 0; idx2 < CFArrayGetCount(interfaces); idx2++) {
+                       CFNumberRef db_type;
+                       CFNumberRef db_unit;
+                       CFDictionaryRef dict = CFArrayGetValueAtIndex(interfaces, idx2);
+                       
+                       db_type = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceType));
+                       db_unit = CFDictionaryGetValue(dict, CFSTR(kIOInterfaceUnit));
+                       res = CFNumberCompare(if_type, db_type, NULL);
+                       if (res == kCFCompareLessThan
+                       || (res == kCFCompareEqualTo
+                       && (CFNumberCompare(if_unit, db_unit, NULL) == kCFCompareLessThan))) {
+                               break;
+                       }
+               }
+               
+               CFArrayInsertValueAtIndex(interfaces, idx2, interfaceEntity);
+               CFRelease(interfaceEntity);
+               
+       }
+       SCPreferencesSetValue(ni_prefs, INTERFACES, interfaces);
+       
+       model = SCPreferencesGetValue(ni_prefs, MODEL);
+       if (model == NULL) {
+               model = _SC_hw_model(FALSE);
+               SCPreferencesSetValue(ni_prefs, MODEL, model);
+       }
+done:
+       if (interfaces != NULL) {
+               CFRelease(interfaces);
+       }
+       if (networkInterfaces != NULL) {
+               CFRelease(networkInterfaces);
+       }
+       
+       return ni_prefs;
+}
+
+
+/*
+ *  _SCNetworkConfigurationPerformMigration will migrate configuration between source and destination systems
+ */
+CF_RETURNS_RETAINED
+CFArrayRef
+_SCNetworkConfigurationPerformMigration(CFURLRef sourceDir, CFURLRef currentDir, CFURLRef targetDir, CFDictionaryRef options)
+{
+       CFURLRef currentDirConfig = NULL;
+       CFURLRef currentSystemPath = NULL;
+       Boolean migrationComplete = FALSE;
+       CFArrayRef paths = NULL;
+       Boolean removeTargetOnFailure = FALSE;
+       CFURLRef sourceDirConfig = NULL;
+       CFURLRef targetDirConfig = NULL;
+       
+       if (getenv(INSTALL_ENVIRONMENT) != NULL) {
+               _sc_debug = 1;
+       }
+
+       // Both sourceDir and currentDir cannot be NULL because NULL value indicates using current system
+       if (sourceDir == NULL && currentDir == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Both sourceDir and currentDir are NULL"));
+               goto done;
+       }
+
+       currentSystemPath = CFURLCreateWithString(NULL,
+                                                 PREFS_DEFAULT_DIR,
+                                                 NULL);
+
+       // if either of the sourceDir or currentDir are NULL, then populate it with current system path
+       if (sourceDir == NULL) {
+               sourceDirConfig = CFRetain(currentSystemPath);
+       }
+       else {
+               sourceDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, sourceDir);
+       }
+
+       if (currentDir != NULL) {
+               currentDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, currentDir);
+       }
+       // If the targetDir is not provided then migration will take place in currentDir
+       if (targetDir == NULL) {
+               targetDirConfig = CFRetain(currentSystemPath);
+       }
+       else {
+               targetDirConfig = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, targetDir);
+       }
+       // Source directory cannot be the same as Target Directory
+       if (CFEqual(sourceDirConfig, targetDirConfig)) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Source directory cannot be the same as target directory"));
+               goto done;
+       }
+       
+       if ((currentDirConfig == NULL) || (CFEqual(currentDirConfig, targetDirConfig) == FALSE)) {
+               if (_SCNetworkConfigurationMakePathIfNeeded(targetDirConfig) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Could not create target directory as expected"));
+                       goto done;
+               }
+
+               if (SCNetworkConfigurationCopyConfigurationFiles(currentDirConfig, targetDirConfig) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration: Could not copy configuration files from %@ to %@"),
+                             currentDirConfig, targetDirConfig);
+               }
+               else if (currentDirConfig != NULL) {
+                       removeTargetOnFailure = TRUE;   // Configuration files were copied over to target directory
+                                                       // If migration failed, then we should remove those configuration
+                                                       // files since current directory and target directory are not
+                                                       // the same
+               }
+       }
+
+       // If both source and current configurations point to current system, then no migration needs to be done.
+       if ((currentDirConfig != NULL) && (CFEqual(sourceDirConfig, currentDirConfig) == TRUE)) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationPerformMigration:  both source and current configurations point to same path ... No migration needs to be done"));
+               migrationComplete = TRUE;
+       }
+       else {
+               migrationComplete = _SCNetworkConfigurationMigrateConfiguration(sourceDirConfig, targetDirConfig);
+       }
+       SCLog(TRUE, LOG_NOTICE, CFSTR("Migration %s"), migrationComplete ? "complete" : "failed");
+       if (migrationComplete == TRUE) {
+               paths = _SCNetworkConfigurationCopyMigrationPaths(NULL);
+       }
+       else {
+               // If migration fails, then remove configuration files from target config if they are
+               // copied from the current directory
+               if (removeTargetOnFailure == TRUE) {
+                       _SCNetworkConfigurationRemoveConfigurationFiles(targetDirConfig);
+               }
+       }
+done:
+       if (currentDirConfig != NULL) {
+               CFRelease(currentDirConfig);
+       }
+       if (currentSystemPath != NULL) {
+               CFRelease(currentSystemPath);
+       }
+       if (sourceDirConfig != NULL) {
+               CFRelease(sourceDirConfig);
+       }
+       if (targetDirConfig != NULL) {
+               CFRelease(targetDirConfig);
+       }
+       return paths;
+}
+
+static Boolean
+_SCNetworkConfigurationMigrateIsFilePresent(CFURLRef filePath)
+{
+       Boolean fileExists = false;
+       char filePathStr[PATH_MAX];
+       int statResult = 0;
+       struct stat statStruct = {0, };
+
+       if (filePath == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateIsFilePresent: filePath is NULL"));
+               goto done;
+       }
+
+       if (CFURLGetFileSystemRepresentation(filePath, TRUE, (UInt8*) filePathStr, sizeof(filePathStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateIsFilePresent: Couldn't get file system representation\n"));
+               goto done;
+       }
+
+       statResult = stat(filePathStr, &statStruct);
+
+       if (statResult == 0) {
+               fileExists = TRUE;
+       }
+done:
+       return fileExists;
+}
+
+static Boolean
+__SCNetworkConfigurationMigrateConfigurationFilesPresent(CFURLRef baseURL, CFArrayRef* migrationPaths)
+{
+       Boolean configFilesPresent = FALSE;
+       CFIndex count;
+       CFURLRef filePath = NULL;
+       CFURLRef interfaces;
+       CFMutableArrayRef migrationPathsMutable = NULL;
+       CFURLRef prefs;
+
+       if (baseURL == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("__SCNetworkConfigurationMigrateConfigurationFilesPresent: baseURL is NULL"));
+               goto done;
+       }
+
+       _SCNetworkConfigurationCopyMigrationPathsWithBaseURL(baseURL, &prefs, &interfaces);
+
+       migrationPathsMutable = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+       CFArrayInsertValueAtIndex(migrationPathsMutable, PREFERENCES_PLIST_INDEX, prefs);
+       CFArrayInsertValueAtIndex(migrationPathsMutable, NETWORK_INTERFACES_PLIST_INDEX, interfaces);
+
+       CFRelease(prefs);
+       CFRelease(interfaces);
+
+       *migrationPaths = migrationPathsMutable;
+
+       if ((*migrationPaths == NULL) ||
+           ((count = CFArrayGetCount(*migrationPaths)) == 0)) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("__SCNetworkConfigurationMigrateConfigurationFilesPresent: migrationPath is NULL or number of elements in migrationPath array is 0"));
+               goto done;
+       }
+
+       for (CFIndex idx = 0; idx < count; idx++) {
+               filePath = CFArrayGetValueAtIndex(*migrationPaths, idx);
+               if (_SCNetworkConfigurationMigrateIsFilePresent(filePath) ==  FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("__SCNetworkConfigurationMigrateConfigurationFilesPresent: File not present: %@"), filePath);
+                       goto done;
+               }
+       }
+
+       configFilesPresent = TRUE;      // all necessary configuration files present
+done:
+       return configFilesPresent;
+}
+
+
+static CFMutableArrayRef
+_SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences     (SCPreferencesRef   ni_prefs, Boolean isBuiltin)
+{
+       CFIndex count = 0;
+       SCNetworkInterfaceRef interface;
+       CFArrayRef interfaceList = NULL;
+       CFMutableArrayRef resultInterfaceList = NULL;
+
+       interfaceList = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
+       if (interfaceList == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences: interfaceList is NULL"));
+               goto done;
+       }
+
+       count = CFArrayGetCount(interfaceList);
+       if (count > 0) {
+               resultInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       }
+
+       for (CFIndex i = 0; i < count; i++) {
+               interface = CFArrayGetValueAtIndex(interfaceList, i);
+
+               if (_SCNetworkInterfaceIsBuiltin(interface) == isBuiltin) {
+                       CFArrayAppendValue(resultInterfaceList, interface);
+               }
+       }
+
+done:
+       if (interfaceList != NULL) {
+               CFRelease(interfaceList);
+       }
+       return resultInterfaceList;
+}
+
+static CFMutableDictionaryRef
+_SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(SCPreferencesRef ni_prefs)
+{
+       CFNumberRef cfMaxUnit;
+       CFIndex count = 0;
+       CFArrayRef ifList = NULL;
+       SCNetworkInterfaceRef interface;
+       CFMutableDictionaryRef InterfaceTypeToMaxUnitMapping = NULL;
+       CFNumberRef type;
+       CFNumberRef unit;
+
+       ifList = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
+
+       if (ifList == NULL) {
+               SCLog(TRUE, LOG_ERR, CFSTR("_SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType: ifList is NULL"));
+               return 0;
+       }
+
+       InterfaceTypeToMaxUnitMapping = CFDictionaryCreateMutable(NULL, 0,
+                                                                   &kCFTypeDictionaryKeyCallBacks,
+                                                                   &kCFTypeDictionaryValueCallBacks);
+       count = CFArrayGetCount(ifList);
+
+       for (CFIndex idx = 0; idx < count; idx++) {
+               cfMaxUnit = NULL;
+               interface = CFArrayGetValueAtIndex(ifList, idx);
+
+               if (isA_SCNetworkInterface(interface) == NULL) {
+                       continue;
+               }
+
+               type  = _SCNetworkInterfaceGetIOInterfaceType(interface);
+
+               if (isA_CFNumber(type) == NULL) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType: type is NULL"));
+                       continue;
+               }
+
+               if (CFDictionaryContainsKey(InterfaceTypeToMaxUnitMapping, type) == FALSE) {
+                       int temp = 0;
+                       cfMaxUnit = CFNumberCreate(NULL, kCFNumberIntType, &temp);
+                       CFDictionaryAddValue(InterfaceTypeToMaxUnitMapping, type, cfMaxUnit);
+                       CFRelease(cfMaxUnit);
+               }
+
+               if (cfMaxUnit == NULL) {
+                       cfMaxUnit = CFDictionaryGetValue(InterfaceTypeToMaxUnitMapping, type);
+               }
+
+               unit = _SCNetworkInterfaceGetIOInterfaceUnit(interface);
+
+               if (isA_CFNumber(unit) == NULL) {
+                       continue;
+               }
+
+               if (CFNumberCompare(unit, cfMaxUnit, NULL) == kCFCompareGreaterThan) {
+                       CFDictionarySetValue(InterfaceTypeToMaxUnitMapping, type, unit);
+               }
+       }
+       if (ifList != NULL) {
+               CFRelease(ifList);
+       }
+       return InterfaceTypeToMaxUnitMapping;
+}
+
+static CFMutableDictionaryRef
+_SCNetworkConfigurationCopyBuiltinMapping (SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs)
+{
+       CFMutableDictionaryRef builtinMapping = NULL;
+       CFIndex sourceBuiltinInterfaceCount = 0;
+       CFMutableArrayRef sourceBuiltinInterfaces = NULL;
+       SCNetworkInterfaceRef sourceInterface;
+       CFIndex targetBuiltinInterfaceCount = 0;
+       CFMutableArrayRef targetBuiltinInterfaces = NULL;
+       SCNetworkInterfaceRef targetInterface;
+
+       sourceBuiltinInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourcePrefs, TRUE);
+       if (isA_CFArray(sourceBuiltinInterfaces) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyBuiltinMapping: sourceBuiltinInterfaces is NULL"));
+               goto done;
+       }
+       sourceBuiltinInterfaceCount = CFArrayGetCount(sourceBuiltinInterfaces);
+
+       targetBuiltinInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetPrefs, TRUE);
+       if (isA_CFArray(targetBuiltinInterfaces) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyBuiltinMapping: targetBuiltinInterfaces is NULL"));
+               goto done;
+       }
+       targetBuiltinInterfaceCount = CFArrayGetCount(targetBuiltinInterfaces);
+
+       // Builtin Mapping will try to map all source interfaces into target interfaces
+       for (CFIndex idx = 0; idx < sourceBuiltinInterfaceCount; idx++) {
+               sourceInterface = CFArrayGetValueAtIndex(sourceBuiltinInterfaces, idx);
+               for (CFIndex idx2 = 0; idx2 < targetBuiltinInterfaceCount; idx2++) {
+                       targetInterface = CFArrayGetValueAtIndex(targetBuiltinInterfaces, idx2);
+
+                       if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, FALSE) == TRUE) {
+                               if (builtinMapping == NULL) {
+                                       builtinMapping = CFDictionaryCreateMutable(NULL, 0,
+                                                                                  &kCFTypeDictionaryKeyCallBacks,
+                                                                                  &kCFTypeDictionaryValueCallBacks);
+                               }
+                               CFDictionaryAddValue(builtinMapping, sourceInterface, targetInterface);
+                               CFArrayRemoveValueAtIndex(targetBuiltinInterfaces, idx2);
+                               break;
+                       }
+               }
+               targetBuiltinInterfaceCount = CFArrayGetCount(targetBuiltinInterfaces);
+       }
+
+done:
+       if (sourceBuiltinInterfaces != NULL) {
+               CFRelease(sourceBuiltinInterfaces);
+       }
+       if (targetBuiltinInterfaces != NULL) {
+               CFRelease(targetBuiltinInterfaces);
+       }
+       return builtinMapping;
+}
+
+static CFMutableDictionaryRef
+_SCNetworkConfigurationCopyExternalInterfaceMapping (SCPreferencesRef sourcePref, SCPreferencesRef targetPrefs)
+{
+       CFNumberRef cfMaxTargetUnit = NULL;
+       CFNumberRef currentInterfaceUnit = NULL;
+       CFMutableDictionaryRef externalMapping = NULL;
+       CFMutableDictionaryRef InterfaceTypeToMaxUnitMapping = NULL;
+       int maxTargetUnit;
+       int newTargetUnit;
+       CFIndex sourceExternalInterfaceCount = 0;
+       CFMutableArrayRef sourceExternalInterfaces = NULL;
+       SCNetworkInterfaceRef sourceInterface = NULL;
+       CFIndex targetExternalInterfaceCount = 0;
+       CFMutableArrayRef targetExternalInterfaces = NULL;
+       SCNetworkInterfaceRef targetInterface = NULL;
+       CFNumberRef type;
+
+       sourceExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(sourcePref, FALSE);
+       if (isA_CFArray(sourceExternalInterfaces) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: sourceExternalInterfaces is NULL"));
+               goto done;
+       }
+       sourceExternalInterfaceCount = CFArrayGetCount(sourceExternalInterfaces);
+
+       if (sourceExternalInterfaceCount == 0) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: sourceExternalInterfaceCount is 0"));
+               goto done;
+       }
+
+       targetExternalInterfaces = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(targetPrefs, FALSE);
+       if (isA_CFArray(targetExternalInterfaces) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: targetExternalInterfaces is NULL"));
+               goto done;
+       }
+
+       InterfaceTypeToMaxUnitMapping = _SCNetworkInterfaceStorageCopyMaxUnitPerInterfaceType(targetPrefs);
+       externalMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+       // Map all external interfaces which exist in both source and target
+       for (CFIndex idx = 0; idx < sourceExternalInterfaceCount; idx++) {
+               sourceInterface = CFArrayGetValueAtIndex(sourceExternalInterfaces, idx);
+               targetExternalInterfaceCount = CFArrayGetCount(targetExternalInterfaces);
+               currentInterfaceUnit = NULL;
+
+               for (CFIndex idx2 = 0; idx2 < targetExternalInterfaceCount; idx2++) {
+                       targetInterface = CFArrayGetValueAtIndex(targetExternalInterfaces, idx2);
+
+                       if (_SCNetworkConfigurationIsInterfaceNamerMappable(sourceInterface, targetInterface, TRUE) == TRUE) {
+                               CFDictionaryAddValue(externalMapping, sourceInterface, targetInterface);
+                               CFArrayRemoveValueAtIndex(targetExternalInterfaces, idx2);
+                               break;
+                       }
+               }
+
+               if (CFDictionaryContainsKey(externalMapping, sourceInterface) == FALSE) {
+                       // Create new mappings for external source interfaces which don't exist in the target
+                       type = _SCNetworkInterfaceGetIOInterfaceType(sourceInterface);
+
+                       cfMaxTargetUnit = CFDictionaryGetValue(InterfaceTypeToMaxUnitMapping, type);
+                       if (cfMaxTargetUnit != NULL) {
+                               CFNumberGetValue(cfMaxTargetUnit, kCFNumberIntType, &maxTargetUnit);
+                               newTargetUnit = maxTargetUnit + 1;
+                       }
+                       else {
+                               newTargetUnit = 0;
+                       }
+
+                       cfMaxTargetUnit = CFNumberCreate(NULL, kCFNumberIntType, &newTargetUnit);
+                       CFDictionarySetValue(InterfaceTypeToMaxUnitMapping, type, cfMaxTargetUnit);
+
+                       targetInterface = (SCNetworkInterfaceRef)__SCNetworkInterfaceCreateCopy(NULL, sourceInterface, NULL, NULL);
+
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCopyExternalInterfaceMapping: sourceInterface: %p, target Interface: %p"), sourceInterface, targetInterface);
+
+                       currentInterfaceUnit = _SCNetworkInterfaceGetIOInterfaceUnit(targetInterface);
+
+                       if ((isA_CFNumber(currentInterfaceUnit) == NULL) ||
+                           (CFEqual(currentInterfaceUnit, cfMaxTargetUnit) == FALSE)) {
+                               // Update the interface unit
+                               __SCNetworkInterfaceSetIOInterfaceUnit(targetInterface, cfMaxTargetUnit);
+                       }
+
+                       CFDictionaryAddValue(externalMapping, sourceInterface, targetInterface);
+
+                       CFRelease(targetInterface);
+                       targetInterface = NULL;
+                       CFRelease(cfMaxTargetUnit);
+                       cfMaxTargetUnit = NULL;
+               }
+       }
+done:
+       if (sourceExternalInterfaces != NULL) {
+               CFRelease(sourceExternalInterfaces);
+       }
+       if (targetExternalInterfaces != NULL) {
+               CFRelease(targetExternalInterfaces);
+       }
+       if (InterfaceTypeToMaxUnitMapping != NULL) {
+               CFRelease(InterfaceTypeToMaxUnitMapping);
+       }
+       return externalMapping;
+}
+static Boolean
+__SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStringRef interfaceName2);
+
+static Boolean
+_SCNetworkConfigurationIsInterfaceNamerMappable(SCNetworkInterfaceRef interface1, SCNetworkInterfaceRef interface2, Boolean bypassActive)
+{
+       Boolean interface1IsBuiltin;
+       CFStringRef interface1Prefix;
+       CFStringRef interface1Type;
+       CFStringRef interface1UserDefinedName;
+       Boolean interface2IsBuiltin;
+       CFStringRef interface2Prefix;
+       CFStringRef interface2Type;
+       CFStringRef interface2UserDefinedName;
+
+       if (interface1 == interface2) {
+               // No work needs to be done
+               return TRUE;
+       }
+       interface1IsBuiltin = _SCNetworkInterfaceIsBuiltin(interface1);
+       interface2IsBuiltin = _SCNetworkInterfaceIsBuiltin(interface2);
+
+       interface1UserDefinedName = SCNetworkInterfaceGetLocalizedDisplayName(interface1);
+       interface2UserDefinedName = SCNetworkInterfaceGetLocalizedDisplayName(interface2);
+
+       interface1Type = SCNetworkInterfaceGetInterfaceType(interface1);
+       interface2Type = SCNetworkInterfaceGetInterfaceType(interface2);
+
+       interface1Prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface1);
+       interface2Prefix = _SCNetworkInterfaceGetIOInterfaceNamePrefix(interface2);
+
+       // Check if have same builtin values.
+       // Check if User Defined name matches
+       // Check if SCNetwork Interface Type matches
+
+       if (interface1IsBuiltin != interface2IsBuiltin) {
+               return FALSE;
+       }
+
+       if (_SC_CFEqual(interface1Type, interface2Type) == FALSE) {
+               return FALSE;
+       }
+
+       if (_SC_CFEqual(interface1Prefix, interface2Prefix) == FALSE) {
+               return FALSE;
+       }
+
+       if (_SC_CFEqual(interface1UserDefinedName, interface2UserDefinedName) == FALSE) {
+               // Checking if we have a mismatch because of the name Ethernet and Ethernet 1
+               // Checking if we have a mismatch because of the name Airport and WiFi
+               if ((interface1IsBuiltin == TRUE) &&
+                   (interface2IsBuiltin == TRUE) &&
+                   (__SCNetworkConfigurationInterfaceNameIsEquiv(interface1UserDefinedName, interface2UserDefinedName) == TRUE)) {
+                           return TRUE;
+               }
+               return FALSE;
+       }
+       return TRUE;
+}
+
+static Boolean
+__SCNetworkConfigurationInterfaceNameIsEquiv(CFStringRef interfaceName1, CFStringRef interfaceName2)
+{
+       CFStringRef interfaceArray[] = { CFSTR("iPhone"), CFSTR("iPad"), CFSTR("iPod"), CFSTR("AppleTV") };
+       const int interfaceCount = sizeof(interfaceArray) / sizeof(CFStringRef);
+       CFStringRef portSuffix = CFSTR(", Port 1");
+       
+       if ((isA_CFString(interfaceName1) != NULL) &&
+           (isA_CFString(interfaceName2) != NULL)) {
+               if (CFEqual(interfaceName1, interfaceName2) == FALSE) {
+                       // Check if we are looking at the WiFi interface
+                       if ((CFEqual(interfaceName1, CFSTR("AirPort")) ||
+                            (CFEqual(interfaceName1, CFSTR("Wi-Fi")))) &&
+                           (CFEqual(interfaceName2, CFSTR("AirPort")) ||
+                            (CFEqual(interfaceName2, CFSTR("Wi-Fi"))))) {
+                               return TRUE;
+                       }
+                       
+                       if (((CFEqual(interfaceName1, CFSTR("Ethernet"))) ||
+                            (CFEqual(interfaceName1, CFSTR("Ethernet 1")))) &&
+                           ((CFEqual(interfaceName2, CFSTR("Ethernet"))) ||
+                            (CFEqual(interfaceName2, CFSTR("Ethernet 1"))))) {
+                               return TRUE;
+                       }
+                       
+                       if (((CFStringHasSuffix(interfaceName1, portSuffix) == TRUE) &&
+                           (CFStringCompareWithOptions(interfaceName1, interfaceName2, CFRangeMake(0, (CFStringGetLength(interfaceName1) - CFStringGetLength(portSuffix))), 0) == kCFCompareEqualTo)) ||
+                           ((CFStringHasSuffix(interfaceName2, portSuffix) == TRUE) &&
+                            (CFStringCompareWithOptions(interfaceName2, interfaceName1, CFRangeMake(0, (CFStringGetLength(interfaceName2) - CFStringGetLength(portSuffix))), 0) == kCFCompareEqualTo))) {
+                               return TRUE;
+                       }
+                       
+                       for (CFIndex idx = 0; idx < interfaceCount; idx++) {
+                               CFStringRef tempInterfaceName = interfaceArray[idx];
+                               if ((CFEqual(interfaceName1, tempInterfaceName) == TRUE ||
+                                       __SCNetworkInterfaceMatchesName(interfaceName1, tempInterfaceName) == TRUE) &&
+                                   (CFEqual(interfaceName2, tempInterfaceName) == TRUE  ||
+                                       __SCNetworkInterfaceMatchesName(interfaceName2, tempInterfaceName) == TRUE)) {
+                                       return TRUE;
+                               }
+                       }
+               }
+               else {
+                       return TRUE;
+               }
+       }
+       
+       return FALSE;
+}
+
+typedef struct {
+       CFDictionaryRef interfaceMapping;
+       CFMutableArrayRef interfacesMissingServices;
+} SCNetworkConfigurationMissingServiceContext;
+
+typedef struct {
+       CFDictionaryRef bsdNameToBridgeServices;        // Mapping of BSD Name to SCBridgeInterfaceRef
+       CFDictionaryRef bsdNameToBondServices;          // Mapping of BSD Name to SCBondInterfaceRef
+       CFDictionaryRef bsdNameToVLANServices;          // Mapping of BSD Name to SCVLANInterfaceRef
+       CFDictionaryRef interfaceMapping;
+       Boolean* isValid;
+       CFMutableArrayRef interfaceToBeRemoved; // SCNetworkInterfaceRef. Services containing the interface will be removed
+       CFMutableArrayRef interfaceToBeReplaced;// SCNetworkInterfaceRef. Services containing the interface will be replaced with default service
+       Boolean repair;
+} SCNetworkConfigurationValidityContext;
+
+static void
+_SCNetworkConfigurationValidateInterface (const void *key, const void *value, void *context)
+{
+       CFStringRef bsdName = (CFStringRef)key;
+       SCNetworkConfigurationValidityContext *ctx = (SCNetworkConfigurationValidityContext*)context;
+       CFDictionaryRef bsdNameToBridgeServices = ctx->bsdNameToBridgeServices;
+       CFDictionaryRef bsdNameToBondServices = ctx->bsdNameToBondServices;
+       CFDictionaryRef bsdNameToVLANServices = ctx->bsdNameToVLANServices;
+       SCNetworkInterfaceRef interface = NULL;
+       CFDictionaryRef interfaceMapping = ctx->interfaceMapping;
+       CFStringRef interfaceUserDefinedName = NULL;
+       Boolean repair = ctx->repair;
+       SCNetworkInterfaceRef serviceInterface = (SCNetworkInterfaceRef)value;
+       CFStringRef serviceInterfaceUserDefinedName = NULL;
+       CFMutableArrayRef interfaceToBeRemoved = ctx->interfaceToBeRemoved;
+       CFMutableArrayRef interfaceToBeReplaced = ctx->interfaceToBeReplaced;
+       
+       // No work needs to be done if we have already made determination that configuration somewhere is not valid,
+       // or we don't intend to repair invalid configuration.
+       if ((*ctx->isValid == FALSE) && (repair == FALSE)) {
+               return;
+       }
+
+       // There is no interface present for the service
+       interface = CFDictionaryGetValue(interfaceMapping, bsdName);
+       if (interface == NULL) {
+               if ((((bsdNameToBridgeServices != NULL) && (CFDictionaryContainsKey(bsdNameToBridgeServices, bsdName) == FALSE))) &&
+                   (((bsdNameToBondServices != NULL) && (CFDictionaryContainsKey(bsdNameToBondServices, bsdName) == FALSE))) &&
+                   (((bsdNameToVLANServices != NULL) && (CFDictionaryContainsKey(bsdNameToVLANServices, bsdName) == FALSE)))) {
+                       // Not a virtual interface
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationValidateInterface: There is no real interface with bsd name: %@ for service"), bsdName);
+                       
+                       if (repair == TRUE) {
+                               CFArrayAppendValue(interfaceToBeRemoved, serviceInterface);
+                       }
+                       *ctx->isValid = FALSE;
+               }
+               return;
+       }
+
+       // TODO: Need to compare between both SCNetworkInterfaceRefs
+       interfaceUserDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface);
+       serviceInterfaceUserDefinedName = __SCNetworkInterfaceGetUserDefinedName(serviceInterface);
+
+       if (__SCNetworkConfigurationInterfaceNameIsEquiv(interfaceUserDefinedName, serviceInterfaceUserDefinedName) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationValidateInterface: Interface user defined name: %@ doesn't match service interface user defined name: %@"), interfaceUserDefinedName, serviceInterfaceUserDefinedName);
+               *ctx->isValid = FALSE;
+               // Add service interface to the interfaceToBeReplaced list
+               if (isA_CFArray(interfaceToBeReplaced) != NULL) {
+                       CFArrayAppendValue(interfaceToBeReplaced, interface);
+               }
+               if (isA_CFArray(interfaceToBeRemoved) != NULL) {
+                       CFArrayAppendValue(interfaceToBeRemoved, serviceInterface);
+               }
+               return;
+       }
+}
+
+static void
+_SCNetworkConfigurationCollectMissingService(const void *key, const void *value, void *context)
+{
+       CFStringRef bsdName = (CFStringRef)key;
+       SCNetworkConfigurationMissingServiceContext *ctx = (SCNetworkConfigurationMissingServiceContext*)context;
+       SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)value;
+       CFMutableArrayRef interfacesMissingServices = ctx->interfacesMissingServices;
+       CFDictionaryRef serviceInterfaceMapping = ctx->interfaceMapping;
+
+       if ((isA_SCNetworkInterface(interface) == NULL) ||
+           (_SCNetworkInterfaceIsBuiltin(interface) == FALSE)) {
+               return;
+       }
+
+       // Check if services have mapping for the BSD name of the interface
+       if (CFDictionaryContainsKey(serviceInterfaceMapping, bsdName) == FALSE) {
+               CFArrayAppendValue(interfacesMissingServices, interface); // Adding interface since the corresponding service seems to be missing
+       }
+}
+
+static Boolean
+_SCNetworkConfigurationCreateBuiltinInterfaceServices(SCPreferencesRef pref,
+                                                     SCPreferencesRef ni_pref)
+{
+       SCNetworkConfigurationMissingServiceContext context;
+       SCNetworkInterfaceRef interface = NULL;
+       CFArrayRef interfaces = NULL;
+       CFMutableArrayRef interfacesWithoutService = NULL;
+       CFDictionaryRef mappingBSDNameToInterface = NULL;
+       CFDictionaryRef mappingServiceBSDNameToInterface = NULL;
+       CFIndex missingServiceCount = 0;
+       Boolean success = FALSE;
+
+       interfaces = __SCNetworkInterfaceCopyStoredWithPreferences(ni_pref);
+       if (interfaces == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCreateBuiltinInterfaceServices: interfaces is NULL or not of the correct type"));
+               goto done;
+       }
+
+       mappingBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
+       CFRelease(interfaces);
+       if (isA_CFDictionary(mappingBSDNameToInterface) == NULL) {
+               goto done;
+       }
+
+       interfaces = __SCNetworkServiceCopyAllInterfaces(pref);
+       if (interfaces == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCreateBuiltinInterfaceServices: interfaces is NULL for configPref or not of the correct type"));
+               goto done;
+       }
+       mappingServiceBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
+       CFRelease(interfaces);
+       if (isA_CFDictionary(mappingServiceBSDNameToInterface) == NULL) {
+               goto done;
+       }
+
+       interfacesWithoutService = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       context.interfaceMapping = mappingServiceBSDNameToInterface;
+       context.interfacesMissingServices = interfacesWithoutService;
+
+       CFDictionaryApplyFunction(mappingBSDNameToInterface, _SCNetworkConfigurationCollectMissingService, &context);
+       missingServiceCount = CFArrayGetCount(interfacesWithoutService);
+
+       success = TRUE;
+
+       for (CFIndex idx = 0; idx < missingServiceCount; idx++) {
+               interface = CFArrayGetValueAtIndex(interfacesWithoutService, idx);
+
+               if (__SCNetworkServiceCreate(pref, interface, NULL) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCreateBuiltinInterfaceServices: Could not add service for interface: %@"), interface);
+                       success = FALSE;
+               }
+       }
+done:
+       if (mappingBSDNameToInterface != NULL) {
+               CFRelease(mappingBSDNameToInterface);
+       }
+       if (mappingServiceBSDNameToInterface != NULL) {
+               CFRelease(mappingServiceBSDNameToInterface);
+       }
+       if (interfacesWithoutService != NULL) {
+               CFRelease(interfacesWithoutService);
+       }
+
+       return success;
+}
+
+static void
+add_default_service(const void *value, void *context)
+{
+       SCNetworkSetRef currentSet = NULL;
+       SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)value;
+       SCPreferencesRef prefs = (SCPreferencesRef)context;
+       SCNetworkServiceRef service;
+       
+       service = SCNetworkServiceCreate(prefs, interface);
+       
+       if (service == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: Could not create new service"));
+               goto done;
+       }
+       
+       if (SCNetworkServiceEstablishDefaultConfiguration(service) == FALSE) {
+               SCNetworkServiceRemove(service);
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: SCNetworkServiceEstablishDefaultConfiguration failed"));
+               goto done;
+       }
+       
+       // Add Service to current set
+       currentSet = SCNetworkSetCopyCurrent(prefs);
+       if (currentSet == NULL) {
+               SCNetworkServiceRemove(service);
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: Could not find current set"));
+               goto done;
+       }
+       
+       if (SCNetworkSetAddService(currentSet, service) == FALSE) {
+               SCNetworkServiceRemove(service);
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_default_service: Could not add service to current set"));
+               goto done;
+       }
+done:
+       if (service != NULL) {
+               CFRelease(service);
+       }
+       if (currentSet != NULL) {
+               CFRelease(currentSet);
+       }
+}
+
+static void
+remove_service(const void *value, void *context)
+{
+       SCNetworkInterfaceRef interface;
+       SCNetworkServiceRef service = (SCNetworkServiceRef)value;
+       CFArrayRef toBeRemoved = (CFArrayRef)context;
+       
+       interface = SCNetworkServiceGetInterface(service);
+       
+       if (CFArrayContainsValue(toBeRemoved, CFRangeMake(0, CFArrayGetCount(toBeRemoved)), interface)) {
+               SCNetworkServiceRemove(service);
+       }
+}
+
+static void
+_SCNetworkConfigurationSaveOldConfiguration(SCPreferencesRef prefs)
+{
+       CFAbsoluteTime absoluteTime;
+       CFCalendarRef currentCalendar;
+       int day;
+       int hour;
+       CFStringRef keyList[] = {
+                       kSCPrefCurrentSet,
+                       MODEL,
+                       kSCPrefNetworkServices,
+                       kSCPrefSets,
+                       kSCPrefSystem,
+                       kSCPrefVirtualNetworkInterfaces
+       };
+       CFIndex keyListCount;
+       int minute;
+       int month;
+       int second;
+       int year;
+       
+       currentCalendar = CFCalendarCopyCurrent();
+       absoluteTime = CFAbsoluteTimeGetCurrent();
+       
+       if (CFCalendarDecomposeAbsoluteTime(currentCalendar, absoluteTime, "yMdHms",
+                                           &year, &month, &day, &hour, &minute, &second) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationSaveOldConfiguration: Cannot decompose absolute time"));
+       }
+       keyListCount = (CFIndex)sizeof(keyList)/sizeof(CFStringRef);
+       
+       for (CFIndex idx = 0; idx < keyListCount; idx++) {
+               CFStringRef newKey;
+               CFTypeRef value = SCPreferencesGetValue(prefs, keyList[idx]);
+               
+               if (value != NULL) {
+                       newKey = CFStringCreateWithFormat(NULL, NULL,
+                                                         CFSTR("%d-%d-%d %d:%d:%d : %@"),
+                                                         year, month, day, hour,
+                                                         minute, second, keyList[idx]);
+                       SCPreferencesSetValue(prefs, newKey, value);
+                       CFRelease(newKey);
+               }
+       }
+       CFRelease(currentCalendar);
+}
+
+static Boolean
+_SCNetworkConfigurationRepairUsingPreferences(SCPreferencesRef prefs,
+                                             CFArrayRef interfaceToBeRemoved,
+                                             CFArrayRef interfaceToBeReplaced)
+{
+       CFIndex removeCount;
+       CFIndex replaceCount;
+       CFArrayRef serviceList;
+       
+       removeCount = CFArrayGetCount(interfaceToBeRemoved);
+       replaceCount = CFArrayGetCount(interfaceToBeReplaced);
+       if (removeCount == 0 &&
+           replaceCount == 0) {
+               // We don't have any information to repair
+               return FALSE;
+       }
+       // Backup current preferences before making changes
+       _SCNetworkConfigurationSaveOldConfiguration(prefs);
+       
+       serviceList = SCNetworkServiceCopyAll(prefs);
+       CFArrayApplyFunction(serviceList, CFRangeMake(0, CFArrayGetCount(serviceList)), remove_service, (void*)interfaceToBeRemoved);
+       
+       CFArrayApplyFunction(interfaceToBeReplaced, CFRangeMake(0, replaceCount), add_default_service, (void*)prefs);
+       CFRelease(serviceList);
+       return TRUE;
+}
+
+static void
+validate_bridge(const void *value, void *context)
+{
+       SCBridgeInterfaceRef bridge = (SCBridgeInterfaceRef) value;
+       CFArrayRef memberInterfaces = SCBridgeInterfaceGetMemberInterfaces(bridge);
+       CFMutableArrayRef memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(memberInterfaces); idx++) {
+               CFStringRef bsdName;
+               SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
+               SCNetworkInterfaceRef memberInterface;
+               
+               bsdName = SCNetworkInterfaceGetBSDName(interface);
+               if (bsdName == NULL) {
+                       continue;
+               }
+               
+               // Check if member interface is present
+               memberInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, bsdName);
+               if (memberInterface != NULL) {
+                       CFArrayAppendValue(memberInterfacesMutable, memberInterface);
+                       CFRelease(memberInterface);
+               }
+       }
+       
+       if (CFArrayGetCount(memberInterfacesMutable) == 0) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("validate_bridge: Removing invalid bridge configuration: %@"), bridge);
+               SCBridgeInterfaceRemove(bridge);
+       }
+       else {
+               SCBridgeInterfaceSetMemberInterfaces(bridge, memberInterfacesMutable);
+       }
+       CFRelease(memberInterfacesMutable);
+}
+#if    !TARGET_OS_IPHONE
+static void
+validate_bond(const void *value, void *context)
+{
+       SCBondInterfaceRef bond = (SCBondInterfaceRef)value;
+       CFArrayRef memberInterfaces = SCBondInterfaceGetMemberInterfaces(bond);
+       CFMutableArrayRef memberInterfacesMutable = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(memberInterfaces); idx++) {
+               CFStringRef bsdName;
+               SCNetworkInterfaceRef interface = (SCNetworkInterfaceRef)CFArrayGetValueAtIndex(memberInterfaces, idx);
+               SCNetworkInterfaceRef memberInterface;
+               
+               bsdName = SCNetworkInterfaceGetBSDName(interface);
+               if (bsdName == NULL) {
+                       continue;
+               }
+               
+               // Check if member interface is present
+               memberInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, bsdName);
+               if (memberInterface != NULL) {
+                       CFArrayAppendValue(memberInterfacesMutable, memberInterface);
+                       CFRelease(memberInterface);
+               }
+       }
+       
+       if (CFArrayGetCount(memberInterfacesMutable) == 0) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("validate_bond: Removing invalid bond configuration: %@"), bond);
+               SCBondInterfaceRemove(bond);
+       }
+       else {
+               SCBondInterfaceSetMemberInterfaces(bond, memberInterfacesMutable);
+       }
+       CFRelease(memberInterfacesMutable);
+}
+#endif
+
+static void
+validate_vlan(const void *value, void *context)
+{
+       CFStringRef bsdName;
+       SCNetworkInterfaceRef interface;
+       Boolean isValid = TRUE;
+       SCPreferencesRef ni_prefs = (SCPreferencesRef)context;
+       SCNetworkInterfaceRef physicalInterface;
+       SCVLANInterfaceRef vlan = (SCVLANInterfaceRef)value;
+       
+       physicalInterface = SCVLANInterfaceGetPhysicalInterface(vlan);
+       bsdName = SCNetworkInterfaceGetBSDName(physicalInterface);
+       
+       if (bsdName == NULL) {
+               isValid = FALSE;
+               goto done;
+       }
+       
+       // Check if the physical interface is present
+       interface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ni_prefs, bsdName);
+       if (interface == NULL) {
+               isValid = FALSE;
+               goto done;
+       }
+       CFRelease(interface);
+       
+done:
+       if (isValid == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("validate_vlan: Removing invalid VLAN configuration: %@"), vlan);
+               SCVLANInterfaceRemove(vlan);
+       }
+}
+
+static Boolean
+_SCNetworkConfigurationCheckValidityUsingPreferences(SCPreferencesRef prefs,
+                                                    SCPreferencesRef ni_prefs,
+                                                    CFDictionaryRef options)
+{
+       CFArrayRef allServices = NULL;
+       CFArrayRef allSets = NULL;
+       CFDictionaryRef bsdNameToBridgeServices = NULL;
+       CFDictionaryRef bsdNameToBondServices = NULL;
+       CFDictionaryRef bsdNameToVLANServices = NULL;
+       SCNetworkConfigurationValidityContext context;
+       CFArrayRef interfaces = NULL;
+       Boolean isValid = TRUE;
+       CFDictionaryRef mappingBSDNameToInterface = NULL;
+       CFDictionaryRef mappingServiceBSDNameToInterface = NULL;
+       Boolean repairConfiguration = FALSE;
+       CFArrayRef setServiceOrder = NULL;
+       CFArrayRef setServices = NULL;
+       CFMutableArrayRef interfaceToBeRemoved = NULL;
+       CFMutableArrayRef interfaceToBeReplaced = NULL;
+       
+       
+       if  ((isA_CFDictionary(options) != NULL)) {
+               CFBooleanRef repair = CFDictionaryGetValue(options, kSCNetworkConfigurationRepair);
+               if (isA_CFBoolean(repair) != NULL) {
+                       repairConfiguration = CFBooleanGetValue(repair);
+               }
+       }
+
+       /*
+        Check the validity by:
+        1) Comparing if the interfaces names mentioned in NetworkInterfaces.plist and preferences.plist match
+        Use the functions
+        CFDictionaryRef
+        __SCNetworkInterfaceCreateMappingUsingBSDName(SCPreferencesRef prefs);
+        */
+       interfaces = __SCNetworkInterfaceCopyStoredWithPreferences(ni_prefs);
+       if (isA_CFArray(interfaces) == NULL) {
+               isValid = FALSE;
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: interfaces is NULL or not of the correct type"));
+               goto done;
+       }
+       mappingBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
+       CFRelease(interfaces);
+       if (isA_CFDictionary(mappingBSDNameToInterface) == NULL) {
+               isValid = FALSE;
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: mappingBSDNameToInterface is NULL"));
+               goto done;
+       }
+
+       interfaces = __SCNetworkServiceCopyAllInterfaces(prefs);
+       if (isA_CFArray(interfaces) == NULL) {
+               isValid = FALSE;
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: interfaces is NULL for configPref or not of the correct type"));
+               goto done;
+       }
+       mappingServiceBSDNameToInterface = __SCNetworkInterfaceCreateMappingUsingBSDName(interfaces);
+       CFRelease(interfaces);
+       if (isA_CFDictionary(mappingServiceBSDNameToInterface) == NULL) {
+               isValid = FALSE;
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: mappingServiceBSDNameToInterface is NULL"));
+               goto done;
+       }
+
+       if (repairConfiguration) {
+               interfaceToBeRemoved = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+               interfaceToBeReplaced = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+#if    !TARGET_OS_IPHONE
+               bsdNameToBridgeServices = _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(prefs);
+               bsdNameToBondServices = _SCNetworkMigrationCopyMappingBSDNameToBondServices(prefs);
+               bsdNameToVLANServices = _SCNetworkMigrationCopyMappingBSDNameToVLANServices(prefs);
+#endif
+       }
+       context.interfaceMapping = mappingBSDNameToInterface;
+       context.isValid = &isValid;
+       context.interfaceToBeRemoved = interfaceToBeRemoved;
+       context.interfaceToBeReplaced = interfaceToBeReplaced;
+       context.bsdNameToBridgeServices = bsdNameToBridgeServices;
+       context.bsdNameToBondServices = bsdNameToBondServices;
+       context.bsdNameToVLANServices = bsdNameToVLANServices;
+       context.repair = repairConfiguration;
+
+       CFDictionaryApplyFunction(mappingServiceBSDNameToInterface, _SCNetworkConfigurationValidateInterface, &context);
+
+       if (isValid == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: Found mismatch between interface names in NetworkInterfaces.plist and preferences.plist"));
+               if (repairConfiguration) {
+                       isValid = _SCNetworkConfigurationRepairUsingPreferences(prefs, interfaceToBeRemoved, interfaceToBeReplaced);
+                       if (isValid == FALSE) {
+                               goto done;
+                       }
+                       // Save the changes if repair fixed an invalid configuration
+                       if (SCPreferencesCommitChanges(prefs) == FALSE) {
+                               SCLog(_sc_debug, LOG_NOTICE, CFSTR("Failed to commit changes from the repaired configuration"));
+                       }
+               }
+               else {
+                       goto done;
+               }
+       }
+       /*
+
+        2) Check if all the network services mentioned in the SCNetworkSet are actually present in the SCNetworkService array
+        */
+
+       allServices = SCNetworkServiceCopyAll(prefs);
+       if (isA_CFArray(allServices) == NULL) {
+               isValid = FALSE;
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: allServices is NULL"));
+               goto done;
+       }
+
+       allSets = SCNetworkSetCopyAll(prefs);
+       if (isA_CFArray(allSets) == NULL) {
+               isValid = FALSE;
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: allSets is NULL"));
+               goto done;
+       }
+
+       for (CFIndex idx = 0; ((idx < CFArrayGetCount(allSets)) && isValid); idx++) {
+               SCNetworkSetRef set = CFArrayGetValueAtIndex(allSets, idx);
+
+               if (isA_SCNetworkSet(set) == NULL) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: set is NULL"));
+                       continue;
+               }
+               setServices = SCNetworkSetCopyServices(set);
+               if (setServices == NULL) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: setServices is NULL"));
+                       continue;
+               }
+               for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(setServices); idx2++) {
+                       SCNetworkServiceRef service = CFArrayGetValueAtIndex(setServices, idx2);
+
+                       if (CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service) == FALSE) {
+                               isValid = FALSE;
+                               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidityUsingPreferences: All network services in the network set are not present in SCNetworkService array"));
+                               break;
+                       }
+               }
+               if (isValid == FALSE) {
+                       break;
+               }
+
+               /*
+                3) Check if service IDs in service order do exist in the SET
+                */
+               setServiceOrder = SCNetworkSetGetServiceOrder(set);
+               if (setServiceOrder != NULL) {
+                       for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(setServiceOrder); idx2++) {
+                               SCNetworkServiceRef service = CFArrayGetValueAtIndex(setServiceOrder, idx2);
+                               if ((CFArrayContainsValue(setServiceOrder, CFRangeMake(0, CFArrayGetCount(setServiceOrder)), service) == FALSE) &&
+                                   (CFArrayContainsValue(allServices, CFRangeMake(0, CFArrayGetCount(allServices)), service) == FALSE)) {
+                                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("Service: %@ is not present in the service order for set %@"), service, set);
+                                       break;
+                               }
+                       }
+               }
+               if (setServices != NULL) {
+                       CFRelease(setServices);
+                       setServices = NULL;
+               }
+       }
+       
+       /*
+        4) Check if the virtual network interfaces have valid member interfaces
+        */
+       CFArrayRef bridges = SCBridgeInterfaceCopyAll(prefs);
+       if (bridges != NULL) {
+               CFArrayApplyFunction(bridges, CFRangeMake(0, CFArrayGetCount(bridges)), validate_bridge, (void*)ni_prefs);
+               CFRelease(bridges);
+       }
+#if    !TARGET_OS_IPHONE
+       CFArrayRef bonds = SCBondInterfaceCopyAll(prefs);
+       if (bonds != NULL) {
+               CFArrayApplyFunction(bonds, CFRangeMake(0, CFArrayGetCount(bonds)), validate_bond, (void*)ni_prefs);
+               CFRelease(bonds);
+       }
+#endif
+       CFArrayRef vlans = SCVLANInterfaceCopyAll(prefs);
+       if (vlans != NULL) {
+               CFArrayApplyFunction(vlans, CFRangeMake(0, CFArrayGetCount(vlans)), validate_vlan, (void*)ni_prefs);
+               CFRelease(vlans);
+       }
+
+
+done:
+       if (mappingBSDNameToInterface != NULL) {
+               CFRelease(mappingBSDNameToInterface);
+       }
+       if (mappingServiceBSDNameToInterface != NULL) {
+               CFRelease(mappingServiceBSDNameToInterface);
+       }
+       if (allServices != NULL) {
+               CFRelease(allServices);
+       }
+       if (allSets != NULL) {
+               CFRelease(allSets);
+       }
+       if (bsdNameToBridgeServices != NULL) {
+               CFRelease(bsdNameToBridgeServices);
+       }
+       if (bsdNameToBondServices != NULL) {
+               CFRelease(bsdNameToBondServices);
+       }
+       if (bsdNameToVLANServices != NULL) {
+               CFRelease(bsdNameToVLANServices);
+       }
+       if (setServices != NULL) {
+               CFRelease(setServices);
+       }
+       if (interfaceToBeRemoved != NULL) {
+               CFRelease(interfaceToBeRemoved);
+       }
+       if (interfaceToBeReplaced != NULL) {
+               CFRelease(interfaceToBeReplaced);
+       }
+       return isValid;
+}
+
+Boolean
+_SCNetworkConfigurationCheckValidity(CFURLRef configDir, CFDictionaryRef options)
+{
+       CFURLRef baseURL = NULL;
+       CFURLRef configNetworkInterfaceFile = NULL;
+       CFStringRef configNetworkInterfaceFileString = NULL;
+       SCPreferencesRef configNetworkInterfacePref = NULL;
+       SCPreferencesRef configPref = NULL;
+       CFURLRef configPreferenceFile = NULL;
+       CFStringRef configPreferencesFileString = NULL;
+       CFArrayRef configurationFiles = NULL;
+       Boolean isValid = FALSE;
+       char networkInterfaceStr[PATH_MAX];
+       char prefsStr[PATH_MAX];
+       
+       if (configDir == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidity: Migration files not found in directory: %@"), ((configDir == NULL) ? CFSTR("NULL") : CFURLGetString(configDir)));
+               goto done;
+       }
+       baseURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE,
+                                                             kCFURLPOSIXPathStyle, TRUE, configDir);
+       
+       configPreferenceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseURL);
+       configNetworkInterfaceFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseURL);
+       
+       if (CFURLGetFileSystemRepresentation(configPreferenceFile, TRUE, (UInt8*)prefsStr, sizeof(prefsStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidity: Could not extract preferences information"));
+               goto done;
+       }
+       if (CFURLGetFileSystemRepresentation(configNetworkInterfaceFile, TRUE, (UInt8*)networkInterfaceStr, sizeof(networkInterfaceStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCheckValidity: Could not extract network interface information"));
+               goto done;
+       }
+       
+       configPreferencesFileString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), prefsStr);
+       configNetworkInterfaceFileString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), networkInterfaceStr);
+
+       configPref = SCPreferencesCreate(NULL,
+                                        PLUGIN_ID,
+                                        configPreferencesFileString);
+
+       configNetworkInterfacePref = SCPreferencesCreate(NULL,
+                                                        PLUGIN_ID,
+                                                        configNetworkInterfaceFileString);
+       if ((configPref == NULL) || (configNetworkInterfacePref == NULL)) {
+               goto done;
+       }
+
+       // This function compares preferences.plist and NetworkInterfaces.plist and verifies if the values are correct
+       // Checking interface mismatch for validity
+       isValid = _SCNetworkConfigurationCheckValidityUsingPreferences(configPref, configNetworkInterfacePref, options);
+
+done:
+       if (baseURL != NULL) {
+               CFRelease(baseURL);
+       }
+       if (configurationFiles != NULL) {
+               CFRelease(configurationFiles);
+       }
+       if (configPreferencesFileString != NULL) {
+               CFRelease(configPreferencesFileString);
+       }
+       if (configNetworkInterfaceFileString != NULL) {
+               CFRelease(configNetworkInterfaceFileString);
+       }
+       if (configPref != NULL) {
+               CFRelease(configPref);
+       }
+       if (configNetworkInterfacePref != NULL) {
+               CFRelease(configNetworkInterfacePref);
+       }
+       if (configPreferenceFile != NULL) {
+               CFRelease(configPreferenceFile);
+       }
+       if (configNetworkInterfaceFile != NULL) {
+               CFRelease(configNetworkInterfaceFile);
+       }
+       return isValid;
+}
+
+
+typedef struct {
+       CFMutableArrayRef externalInterfaceList;
+       CFMutableArrayRef networkInterfaceList;
+} SCExternalMappingContext;
+
+static void
+_SCNetworkConfigurationCollectInterfaceStorageEntity(const void *key, const void *value, void *context)
+{
+       SCExternalMappingContext* ctx = context;
+       CFDictionaryRef interface_entity = NULL;
+       SCNetworkInterfaceRef targetInterface = (SCNetworkInterfaceRef)value;
+
+       if (CFArrayContainsValue(ctx->externalInterfaceList, CFRangeMake(0, CFArrayGetCount(ctx->externalInterfaceList)), targetInterface) == TRUE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationCollectInterfaceStorageEntity: Target Interface %@ already exists, thus do no add it to NetworkInterfaces.plist"), targetInterface);
+               return; // If the target interface already exists then do not add it to NetworkInterfaces.plist
+       }
+       interface_entity = __SCNetworkInterfaceCopyStorageEntity(targetInterface);
+
+       if (interface_entity != NULL) {
+               CFArrayAppendValue(ctx->networkInterfaceList, interface_entity);
+               CFRelease(interface_entity);
+       }
+}
+
+static CFArrayRef   // CFDictionaryRef
+_SCNetworkMigrationCreateNetworkInterfaceArray(SCPreferencesRef ni_prefs, CFDictionaryRef externalMapping)
+{
+       SCExternalMappingContext context;
+       CFIndex count = 0;
+       CFMutableArrayRef externalInterfaceList = NULL;
+       CFArrayRef if_list = NULL;
+       CFDictionaryRef interface_entity = NULL;
+       CFMutableArrayRef networkInterfaceList = NULL;
+
+       if (ni_prefs == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateNetworkInterfaceArray: ni_prefs are NULL"));
+               return NULL;
+       }
+
+       if_list = SCPreferencesGetValue(ni_prefs, INTERFACES);
+
+       if ((isA_CFArray(if_list) == NULL) ||
+           ((count = CFArrayGetCount(if_list)) == 0)) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateNetworkInterfaceArray: if_list is NULL or interface count is 0"));
+               return NULL;
+       }
+
+       networkInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       // Keep the same builtin and external interfaces
+       for (CFIndex idx = 0; idx < count; idx++) {
+               interface_entity = CFArrayGetValueAtIndex(if_list, idx);
+               if (isA_CFDictionary(interface_entity) == NULL) {
+                       continue;
+               }
+               CFArrayAppendValue(networkInterfaceList, interface_entity);
+       }
+
+       if (isA_CFDictionary(externalMapping) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateNetworkInterfaceArray: externalMapping is NULL or not of the correct type"));
+               goto done;
+       }
+       // Add any new external interfaces found
+       externalInterfaceList = _SCNetworkInterfaceCopyInterfacesFilteredByBuiltinWithPreferences(ni_prefs, FALSE);
+       context.externalInterfaceList = externalInterfaceList;
+       context.networkInterfaceList = networkInterfaceList;
+
+       CFDictionaryApplyFunction(externalMapping, _SCNetworkConfigurationCollectInterfaceStorageEntity, &context);
+
+done:
+       if (externalInterfaceList != NULL) {
+               CFRelease(externalInterfaceList);
+       }
+       return networkInterfaceList;
+}
+
+static void
+SCNetworkMigrationMapSourceToTargetName(const void *key, const void *value, void *context)
+{
+       SCNetworkInterfaceRef interfaceKey = (SCNetworkInterfaceRef)key;
+       SCNetworkInterfaceRef interfaceValue = (SCNetworkInterfaceRef)value;
+       CFMutableDictionaryRef mapping = (CFMutableDictionaryRef)context;
+       CFStringRef sourceBSDName = NULL;
+       CFStringRef targetBSDName = NULL;
+
+       sourceBSDName = SCNetworkInterfaceGetBSDName(interfaceKey);
+       if (isA_CFString(sourceBSDName) == NULL) {
+               return;
+       }
+
+       targetBSDName = SCNetworkInterfaceGetBSDName(interfaceValue);
+       if (isA_CFString(targetBSDName) == NULL) {
+               return;
+       }
+
+       if (CFDictionaryContainsKey(mapping, sourceBSDName) == FALSE) {
+               CFDictionaryAddValue(mapping, sourceBSDName, targetBSDName);
+       }
+       return;
+}
+
+static CFDictionaryRef
+_SCNetworkMigrationCreateBSDNameMapping(CFDictionaryRef internalMapping, CFDictionaryRef externalMapping)
+{
+       CFMutableDictionaryRef bsdNameMapping = CFDictionaryCreateMutable(NULL, 0,
+                                                                         &kCFTypeDictionaryKeyCallBacks,
+                                                                         &kCFTypeDictionaryValueCallBacks);
+
+       if ((internalMapping == NULL) && externalMapping == NULL) {
+               goto done;
+       }
+       
+       if (internalMapping != NULL) {
+               CFDictionaryApplyFunction(internalMapping, SCNetworkMigrationMapSourceToTargetName, bsdNameMapping);
+       }
+
+       if (externalMapping != NULL) {
+               CFDictionaryApplyFunction(externalMapping, SCNetworkMigrationMapSourceToTargetName, bsdNameMapping);
+       }
+       
+done:
+       return bsdNameMapping;
+}
+
+typedef struct {
+       CFMutableArrayRef mutableServiceArray;
+       SCPreferencesRef prefs;
+} SCNetworkServiceArrayCopyContext;
+
+static CFDictionaryRef
+_SCNetworkMigrationCreateServiceSetMapping(SCPreferencesRef prefs)
+{
+       CFMutableDictionaryRef serviceSetMapping = CFDictionaryCreateMutable(NULL, 0,
+                                                                            &kCFTypeDictionaryKeyCallBacks,
+                                                                            &kCFTypeDictionaryValueCallBacks);
+       SCNetworkServiceRef service = NULL;
+       CFArrayRef services = NULL;
+       CFMutableArrayRef setList = NULL;
+       CFArrayRef sets = NULL;
+       
+       services = SCNetworkServiceCopyAll(prefs);
+       if (services == NULL) {
+               goto done;
+       }
+       for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
+               service = CFArrayGetValueAtIndex(services, idx);
+               
+               if (CFDictionaryContainsKey(serviceSetMapping, service) == FALSE) {
+                       setList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                       CFDictionaryAddValue(serviceSetMapping, service, setList);
+                       CFRelease(setList);
+               }
+       }
+       CFRelease(services);
+       
+       sets = SCNetworkSetCopyAll(prefs);
+       if (sets == NULL) {
+               goto done;
+       }
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(sets); idx++) {
+               SCNetworkSetRef set = CFArrayGetValueAtIndex(sets, idx);
+               services = SCNetworkSetCopyServices(set);
+               
+               for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(services); idx2++) {
+                       service = CFArrayGetValueAtIndex(services, idx2);
+                       setList = (CFMutableArrayRef)CFDictionaryGetValue(serviceSetMapping, service);
+                       if (setList != NULL) {
+                               CFArrayAppendValue(setList, set);
+                       }
+               }
+               CFRelease(services);
+       }
+       
+done:
+       if (sets != NULL) {
+               CFRelease(sets);
+       }
+       return serviceSetMapping;
+}
+
+static CFDictionaryRef
+_SCNetworkMigrationCreateSetMapping(SCPreferencesRef sourcePrefs,
+                                   SCPreferencesRef targetPrefs)
+{
+       SCNetworkSetRef currentSourceSet = NULL;
+       CFMutableDictionaryRef setMapping = NULL;
+       CFStringRef setName;
+       CFArrayRef sourceSets = NULL;
+       CFArrayRef targetSets = NULL;
+       CFMutableArrayRef targetSetsMutable = NULL;
+       
+       sourceSets = SCNetworkSetCopyAll(sourcePrefs);
+       targetSets = SCNetworkSetCopyAll(targetPrefs);
+       
+       if (sourceSets == NULL ||
+           targetSets == NULL) {
+               goto done;
+       }
+       targetSetsMutable = CFArrayCreateMutableCopy(NULL, 0, targetSets);
+       
+       setMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       
+       currentSourceSet = SCNetworkSetCopyCurrent(sourcePrefs);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(sourceSets); idx++) {
+               SCNetworkSetRef sourceSet = CFArrayGetValueAtIndex(sourceSets, idx);
+               CFIndex targetCount = CFArrayGetCount(targetSetsMutable);
+               SCNetworkSetRef targetSet;
+               
+               setName = SCNetworkSetGetName(sourceSet);
+               if (targetCount > 0) {
+                       targetSet = CFArrayGetValueAtIndex(targetSetsMutable, 0);
+                       CFRetain(targetSet);
+                       CFArrayRemoveValueAtIndex(targetSetsMutable, 0);
+               }
+               else {
+                       targetSet = SCNetworkSetCreate(targetPrefs);
+               }
+               
+               SCNetworkSetSetName(targetSet, setName);
+               CFDictionaryAddValue(setMapping, sourceSet, targetSet);
+               
+               if (CFEqual(sourceSet, currentSourceSet) == TRUE) {
+                       SCNetworkSetSetCurrent(targetSet);
+               }
+               CFRelease(targetSet);
+       }
+       
+done:
+       if (sourceSets != NULL) {
+               CFRelease(sourceSets);
+       }
+       if (targetSets != NULL) {
+               CFRelease(targetSets);
+       }
+       if (targetSetsMutable != NULL) {
+               CFRelease(targetSetsMutable);
+       }
+       if (currentSourceSet != NULL) {
+               CFRelease(currentSourceSet);
+       }
+       return setMapping;
+}
+
+// This function finds the mapping between source and target preferences (SCNetworkServicesRef -> SCNetworkServicesRef)
+// If there is no mapping found between source and target preferences, then the CFBooleanRef value indicating no value is found is stored (SCNetworkServicesRef -> kCFBooleanFalse)
+static CFDictionaryRef
+_SCNetworkMigrationCreateServiceMappingUsingBSDMapping(SCPreferencesRef sourcePrefs,
+                                                      SCPreferencesRef targetPrefs,
+                                                      CFDictionaryRef bsdNameMapping)
+{
+       CFStringRef bsdNameMapTarget = NULL;
+       CFMutableDictionaryRef serviceMapping = NULL;                               // Mapping of services between source and target configurations
+       CFStringRef sourceBSDName = NULL;
+       CFIndex sourceCount = 0;
+       SCNetworkInterfaceRef sourceInterface = NULL;
+       CFStringRef sourceInterfaceSubType = NULL;              // Check interface type and subtype to be able to transfer VPN
+       CFStringRef sourceInterfaceType = NULL;
+       CFArrayRef sourceSCNetworkServices = NULL;
+       CFMutableArrayRef sourceSCNetworkServicesMutable = NULL;                    // Source SCNetworkServiceRef mutable array
+       SCNetworkServiceRef sourceService = NULL;
+       CFStringRef targetBSDName = NULL;
+       CFIndex targetCount = 0;                                   // Count of Source and Target Services
+       SCNetworkInterfaceRef targetInterface = NULL;
+       CFStringRef targetInterfaceSubType = NULL;              // services during migration
+       CFStringRef targetInterfaceType = NULL;
+       CFArrayRef targetSCNetworkServices = NULL;
+       CFMutableArrayRef targetSCNetworkServicesMutable = NULL;                    // Target SCNetworkServiceRef mutable array
+       SCNetworkServiceRef targetService = NULL;
+
+       // We need BSD Mapping to successfully create service mapping
+       if (bsdNameMapping == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: BSD Name Mapping is NULL"));
+               goto done;
+       }
+       sourceSCNetworkServices = SCNetworkServiceCopyAll(sourcePrefs);
+       if (isA_CFArray(sourceSCNetworkServices) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: sourceSCNetworkServices is NULL or not of the correct CFType"));
+               goto done;
+       }
+       targetSCNetworkServices = SCNetworkServiceCopyAll(targetPrefs);
+       if (isA_CFArray(targetSCNetworkServices) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetSCNetworkServices is NULL or not of the correct CFType"));
+               goto done;
+       }
+
+       sourceCount = CFArrayGetCount(sourceSCNetworkServices);
+
+       sourceSCNetworkServicesMutable = CFArrayCreateMutableCopy(NULL, 0, sourceSCNetworkServices);
+       targetSCNetworkServicesMutable = CFArrayCreateMutableCopy(NULL, 0, targetSCNetworkServices);
+
+       serviceMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+       for (CFIndex idx = 0;  idx < sourceCount; idx++) {
+               sourceBSDName = NULL;
+               sourceService = NULL;
+               sourceInterface = NULL;
+               sourceInterfaceType = NULL;
+               sourceInterfaceSubType = NULL;
+               bsdNameMapTarget = NULL;
+
+               targetCount = CFArrayGetCount(targetSCNetworkServicesMutable);
+               sourceService = (SCNetworkServiceRef) CFArrayGetValueAtIndex(sourceSCNetworkServicesMutable, idx);
+
+               sourceInterface = SCNetworkServiceGetInterface(sourceService);
+
+               if (sourceInterface == NULL) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: sourceInterface is NULL or not of the correct type"));
+                       continue;
+               }
+
+               sourceInterfaceType = __SCNetworkInterfaceGetEntityType(sourceInterface);
+               if ((isA_CFString(sourceInterfaceType) != NULL) &&
+                   ((CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeVPN) == TRUE) ||
+                    (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypePPP) == TRUE))) {
+                           sourceInterfaceSubType = __SCNetworkInterfaceGetEntitySubType(sourceInterface);
+                           if (isA_CFString(sourceInterfaceSubType) == NULL) {
+                                   SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: sourceInterfaceSubType is NULL or not of the correct type"));
+                                   continue;
+                           }
+               }
+               else if (((isA_CFString(sourceInterfaceType) != NULL) &&
+                         (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeIPSec) == FALSE) &&
+                         (CFEqual(sourceInterfaceType, kSCValNetInterfaceType6to4) == FALSE) &&
+                         (CFEqual(sourceInterfaceType, kSCValNetInterfaceTypeLoopback) == FALSE)) ||
+                        (isA_CFString(sourceInterfaceType) == NULL)) {
+                       sourceBSDName = SCNetworkInterfaceGetBSDName(sourceInterface);
+                       if ((isA_CFString(sourceBSDName) == NULL) ||
+                           (CFDictionaryContainsKey(bsdNameMapping, sourceBSDName)) == FALSE) {
+                               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: bsdNameMapping doesn't contain sourceBSDName: %@"), (sourceBSDName == NULL) ? CFSTR("NULL") : sourceBSDName);
+                               continue;
+                       }
+
+                       bsdNameMapTarget = CFDictionaryGetValue(bsdNameMapping, sourceBSDName);
+                       if (isA_CFString(bsdNameMapTarget) == NULL) {
+                               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: bsdNameMapTarget is NULL or not of the correct CFType"));
+                               continue;
+                       }
+               }
+               // Find the bsd name in target service
+               for (CFIndex idx2 = 0; idx2 < targetCount; idx2++) {
+                       targetService = NULL;
+                       targetInterface = NULL;
+                       targetBSDName = NULL;
+                       targetInterfaceType = NULL;
+                       targetInterfaceSubType = NULL;
+
+                       targetService = (SCNetworkServiceRef) CFArrayGetValueAtIndex(targetSCNetworkServicesMutable, idx2);
+
+                       targetInterface = SCNetworkServiceGetInterface(targetService);
+                       if (targetInterface == NULL) {
+                               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetInterface is NULL or not of the correct type"));
+                               continue;
+                       }
+                        SCLog(_sc_debug, LOG_NOTICE, CFSTR("targetInterface: %@"), targetInterface);
+                       if (sourceBSDName != NULL) {
+                               targetBSDName = SCNetworkInterfaceGetBSDName(targetInterface);
+                               if (isA_CFString(targetBSDName) == NULL) {
+                                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetBSDName is NULL or not of the correct type"));
+                                       continue;
+                               }
+
+                               if (CFEqual(targetBSDName, bsdNameMapTarget) == TRUE) {
+                                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: Removing target BSD Name: %@"), targetBSDName);
+                                       CFDictionaryAddValue(serviceMapping, sourceService, targetService);
+                                       CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
+                                       break;
+                               }
+                       }
+                       else {
+                               // Source Interface Type should be VPN
+                               targetInterfaceType = __SCNetworkInterfaceGetEntityType(targetInterface);
+                               if ((isA_CFString(targetInterfaceType) == NULL) ||
+                                   ((CFEqual(targetInterfaceType, kSCValNetInterfaceTypeVPN) == FALSE) &&
+                                    (CFEqual(targetInterfaceType, kSCValNetInterfaceTypePPP) == FALSE))) {
+                                           SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetInterfaceType is NULL or not of the correct type : %@"), (targetInterfaceType != NULL) ? targetInterfaceType : CFSTR("NULL"));
+                                           continue;
+                                   }
+                               targetInterfaceSubType = __SCNetworkInterfaceGetEntitySubType(targetInterface);
+                               if (isA_CFString(targetInterfaceSubType) == NULL) {
+                                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: targetInterfaceSubType is NULL or not of the correct type: %@"), (targetInterfaceSubType != NULL) ? targetInterfaceSubType : CFSTR("NULL"));
+                                       continue;
+                               }
+
+                               // Check if the target interface type and the target interface sub type match
+                               if ((CFEqual(targetInterfaceType, sourceInterfaceType) == TRUE) &&
+                                   (CFEqual(targetInterfaceSubType, sourceInterfaceSubType) == TRUE)) {
+                                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: Removing target BSD Name: %@ for VPN"), targetBSDName);
+                                       CFDictionaryAddValue(serviceMapping, sourceService, targetService);
+                                       CFArrayRemoveValueAtIndex(targetSCNetworkServicesMutable, idx2);
+                                       break;
+                               }
+                       }
+               }
+               // Check if sourceService has found a mapping or not, if not the create a NULL mapping to indicate
+               // the this service needs to be added and not replaced
+               if (CFDictionaryContainsKey(serviceMapping, sourceService) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationCreateServiceMappingUsingBSDMapping: Service needs to be added: %@"), sourceService);
+                       CFDictionaryAddValue(serviceMapping, sourceService, kCFBooleanFalse);
+               }
+       }
+done:
+       if (sourceSCNetworkServices != NULL) {
+               CFRelease(sourceSCNetworkServices);
+       }
+       if (targetSCNetworkServices != NULL) {
+               CFRelease(targetSCNetworkServices);
+       }
+       if (sourceSCNetworkServicesMutable != NULL) {
+               CFRelease(sourceSCNetworkServicesMutable);
+       }
+       if (targetSCNetworkServicesMutable != NULL) {
+               CFRelease(targetSCNetworkServicesMutable);
+       }
+       return serviceMapping;
+}
+
+typedef struct {
+       SCPreferencesRef targetPrefs;
+       CFDictionaryRef bsdMapping;
+       CFDictionaryRef setMapping;
+       CFDictionaryRef serviceSetMapping;
+} ServiceMigrationContext;
+
+// value can be:
+//     SCNetworkServiceRef: if target service needs replacement
+//     CFBooleanRef: if target service is not present
+static void
+ServiceMigrationAddOrReplace(const void *key, const void *value, void *context)
+{
+       CFDictionaryRef bsdMapping = NULL;
+       ServiceMigrationContext *ctx = (ServiceMigrationContext*)context;
+       CFDictionaryRef setMapping;
+       CFDictionaryRef sourceServiceSetMapping;
+       SCNetworkServiceRef sourceService = (SCNetworkServiceRef)key;
+       SCPreferencesRef targetPrefs = NULL;
+       SCNetworkServiceRef targetService = (SCNetworkServiceRef)value;
+
+       targetPrefs = ctx->targetPrefs;
+       bsdMapping = ctx->bsdMapping;
+       setMapping = ctx->setMapping;
+       sourceServiceSetMapping = ctx->serviceSetMapping;
+       
+       if (isA_SCNetworkService(targetService) != NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("ServiceMigrationAddOrReplace: Removing target service: %@"), targetService);
+               SCNetworkServiceRemove(targetService);
+       }
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("ServiceMigrationAddOrReplace: Adding service with %@"), sourceService);
+       if (__SCNetworkServiceMigrateNew(targetPrefs, sourceService, bsdMapping, setMapping, sourceServiceSetMapping) ==  FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("Could not Add Service: %@"), sourceService);
+       }
+}
+
+static Boolean
+_SCNetworkMigrationDoServiceMigration(SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs,
+                                     CFDictionaryRef serviceMapping, CFDictionaryRef bsdMapping,
+                                     CFDictionaryRef setMapping, CFDictionaryRef serviceSetMapping)
+{
+       ServiceMigrationContext context;
+       Boolean success = FALSE;
+
+       if ((sourcePrefs == NULL) ||
+           (targetPrefs == NULL) ||
+           (isA_CFDictionary(serviceMapping) == NULL) ||
+           (isA_CFDictionary(bsdMapping) == NULL)) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoServiceMigration: targetPrefs or serviceMapping or bsdMapping is NULL"));
+               goto done;
+       }
+       context.targetPrefs = targetPrefs;
+       context.bsdMapping = bsdMapping;
+       context.setMapping = setMapping;
+       context.serviceSetMapping = serviceSetMapping;
+       
+       CFDictionaryApplyFunction(serviceMapping, ServiceMigrationAddOrReplace, &context);
+
+       success = TRUE;
+done:
+       return success;
+}
+
+static Boolean
+_SCNetworkMigrationDoSystemMigration(SCPreferencesRef sourcePrefs, SCPreferencesRef targetPrefs)
+{
+       CFStringEncoding nameEncoding;
+       CFStringRef computerName;
+       CFStringRef hostname;
+       CFStringRef localHostname;
+       CFDictionaryRef btmm = NULL;
+       CFDictionaryRef btmmDSID = NULL;
+       CFStringRef btmmDSIDPath;
+       CFStringRef btmmPath;
+       
+       
+       if ((sourcePrefs == NULL) ||
+           (targetPrefs == NULL)) {
+               return FALSE;
+       }
+
+       hostname = SCPreferencesGetHostName(sourcePrefs);
+       if (hostname != NULL) {
+               SCPreferencesSetHostName(targetPrefs, hostname);
+       }
+
+       localHostname = _SCPreferencesCopyLocalHostName(sourcePrefs);
+       if (localHostname != NULL) {
+               SCPreferencesSetLocalHostName(targetPrefs, localHostname);
+               CFRelease(localHostname);
+       }
+
+       computerName = _SCPreferencesCopyComputerName(sourcePrefs, &nameEncoding);
+
+       if (computerName != NULL) {
+               SCPreferencesSetComputerName(targetPrefs, computerName, nameEncoding);
+               CFRelease(computerName);
+       }
+       
+       btmmPath = CFStringCreateWithFormat(NULL, NULL,
+                                           CFSTR("/%@/%@/%@"),
+                                           kSCPrefSystem,
+                                           kSCCompNetwork,
+                                           BACK_TO_MY_MAC);
+       btmm = SCPreferencesPathGetValue(sourcePrefs, btmmPath);
+       
+       if (btmm != NULL) {
+               SCPreferencesPathSetValue(targetPrefs, btmmPath, btmm);
+       }
+       CFRelease(btmmPath);
+       
+       btmmDSIDPath = CFStringCreateWithFormat(NULL, NULL,
+                                               CFSTR("/%@/%@/%@"),
+                                               kSCPrefSystem,
+                                               kSCCompNetwork,
+                                               BACK_TO_MY_MAC_DSIDS);
+       
+       btmmDSID = SCPreferencesPathGetValue(sourcePrefs, btmmDSIDPath);
+       if (btmmDSID != NULL) {
+               SCPreferencesPathSetValue(targetPrefs, btmmDSIDPath, btmmDSID);
+       }
+       CFRelease(btmmDSIDPath);
+
+       return TRUE;
+}
+#if    !TARGET_OS_IPHONE
+
+typedef struct {
+       CFMutableArrayRef interfaceList;
+       SCPreferencesRef ni_prefs;
+       CFDictionaryRef bsdMapping;
+} SCVirtualInterfaceMemberListContext;
+
+typedef struct {
+       SCPreferencesRef prefs;
+       SCPreferencesRef ni_prefs;
+       CFDictionaryRef bsdMapping;
+       CFDictionaryRef virtualBSDMapping;
+       CFDictionaryRef mappingBSDNameToService;
+       CFDictionaryRef setMapping;
+       CFDictionaryRef serviceSetMapping;
+} SCVirtualInterfaceContext;
+
+static void
+add_virtual_interface(const void *value, void *context)
+{
+       SCVirtualInterfaceMemberListContext *ctx = (SCVirtualInterfaceMemberListContext*)context;
+       CFMutableArrayRef interfaceList = ctx->interfaceList;
+       CFDictionaryRef bsdMapping = ctx->bsdMapping;
+       CFStringRef oldInterfaceBSDName = (CFStringRef)value;
+       SCNetworkInterfaceRef newInterface;
+       CFStringRef newInterfaceBSDName;
+       
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("old interface BSD name is %@"), oldInterfaceBSDName);
+       newInterfaceBSDName = CFDictionaryGetValue(bsdMapping, oldInterfaceBSDName);
+       if (newInterfaceBSDName == NULL) {
+               return;
+       }
+       
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("new interface BSD name is %@"), newInterfaceBSDName);
+       newInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ctx->ni_prefs, newInterfaceBSDName);
+       
+       if (newInterface != NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("Adding interface to interfaceList: %@"), newInterface);
+               CFArrayAppendValue(interfaceList, newInterface);
+               CFRelease(newInterface);
+       }
+       return;
+}
+
+static void
+add_target_bridge(const void *key, const void *value, void *context)
+{
+       CFStringRef bridgeName;
+       CFDictionaryRef bridgeOptions;
+       SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
+       CFDictionaryRef bridgeBSDNameMapping = ctx->virtualBSDMapping;
+       CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
+       SCVirtualInterfaceMemberListContext memberListContext;
+       CFMutableArrayRef newInterfaceList;
+       SCBridgeInterfaceRef newBridge;
+       SCBridgeInterfaceRef oldBridge = (SCBridgeInterfaceRef)key;
+       CFStringRef oldBSDName;
+       CFArrayRef oldInterfaceList = (CFArrayRef)value;
+       CFArrayRef oldServiceList;
+       SCPreferencesRef prefs = ctx->prefs;
+       CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
+       CFDictionaryRef setMapping = ctx->setMapping;
+       
+       newInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       
+       memberListContext.bsdMapping = ctx->bsdMapping;
+       memberListContext.interfaceList = newInterfaceList;
+       memberListContext.ni_prefs = ctx->ni_prefs;
+       
+       CFArrayApplyFunction(oldInterfaceList, CFRangeMake(0, CFArrayGetCount(oldInterfaceList)), add_virtual_interface, &memberListContext);
+       
+       newBridge = SCBridgeInterfaceCreate(prefs);
+       
+       if (__SCBridgeInterfaceSetMemberInterfaces(newBridge, newInterfaceList) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bridge: Adding Member Interfaces failed"));
+       }
+       CFRelease(newInterfaceList);
+       
+       bridgeOptions = SCBridgeInterfaceGetOptions(oldBridge);
+       if (bridgeOptions != NULL) {
+               SCBridgeInterfaceSetOptions(newBridge, bridgeOptions);
+       }
+       
+       bridgeName = SCNetworkInterfaceGetLocalizedDisplayName(oldBridge);
+       
+       if (bridgeName != NULL) {
+               SCBridgeInterfaceSetLocalizedDisplayName(newBridge, bridgeName);
+       }
+       
+       oldBSDName = SCNetworkInterfaceGetBSDName(oldBridge);
+       if (oldBSDName == NULL) {
+               goto done;
+       }
+       
+       oldServiceList = CFDictionaryGetValue(bsdNameToServiceMapping, oldBSDName);
+       if (oldServiceList == NULL) {
+               goto done;
+       }
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
+               SCNetworkServiceRef oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
+               if (__SCNetworkServiceMigrateNew(prefs, oldService, bridgeBSDNameMapping, setMapping, serviceSetMapping) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bridge: Could not migrate service: %@"), oldService);
+               }
+       }
+done:
+       CFRelease(newBridge);
+}
+
+static void
+_SCNetworkMigrationRemoveBridgeServices(SCPreferencesRef prefs)
+{
+       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
+               SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
+               CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
+               
+               if ((bsdName != NULL) &&
+               SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBridge) {
+                       SCLog(TRUE, LOG_NOTICE, CFSTR("_SCNetworkMigrationRemoveBridgeServices: Removing services: %@"), service);
+                       SCNetworkServiceRemove(service);
+               }
+       }
+       CFRelease(services);
+}
+
+
+static CFDictionaryRef
+_SCNetworkMigrationCopyMappingBSDNameToBridgeServices(SCPreferencesRef prefs)
+{
+       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
+       CFMutableDictionaryRef bridgeServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
+               SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
+               CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
+               
+               if ((bsdName != NULL) &&
+               SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBridge) {
+                       CFMutableArrayRef serviceList;
+                       if (CFDictionaryContainsKey(bridgeServices, bsdName) == FALSE) {
+                               serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                               CFDictionaryAddValue(bridgeServices, bsdName, serviceList);
+                               CFRelease(serviceList);
+                       }
+                       serviceList = (CFMutableArrayRef)CFDictionaryGetValue(bridgeServices, bsdName);
+                       CFArrayAppendValue(serviceList, service);
+               }
+       }
+       CFRelease(services);
+       return bridgeServices;
+}
+
+
+static Boolean
+_SCNetworkMigrationDoBridgeMigration (SCPreferencesRef sourcePrefs,
+                                     SCPreferencesRef sourceNIPrefs,
+                                     SCPreferencesRef targetPrefs,
+                                     SCPreferencesRef targetNIPrefs,
+                                     CFDictionaryRef bsdMapping,
+                                     CFDictionaryRef setMapping,
+                                     CFDictionaryRef serviceSetMapping)
+{
+       CFArrayRef allSourceBridges;
+       CFArrayRef allTargetBridges;
+       SCBridgeInterfaceRef bridge;
+       CFMutableDictionaryRef bridgeInterfaceMapping = NULL;
+       CFMutableDictionaryRef bridgeMapping;
+       CFDictionaryRef bsdNameToBridgeServices;
+       SCVirtualInterfaceContext context;
+       CFIndex count = 0;
+       Boolean success = FALSE;
+       
+       allSourceBridges = SCBridgeInterfaceCopyAll(sourcePrefs);
+       allTargetBridges = SCBridgeInterfaceCopyAll(targetPrefs);
+       
+       bsdNameToBridgeServices = _SCNetworkMigrationCopyMappingBSDNameToBridgeServices(sourcePrefs);
+       
+       bridgeInterfaceMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       bridgeMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       
+       // Create Bridge Interface Mapping
+       for (CFIndex idx = 0; idx < CFArrayGetCount(allSourceBridges); idx++) {
+               bridge = CFArrayGetValueAtIndex(allSourceBridges, idx);
+               CFArrayRef bridgeMembers = SCBridgeInterfaceGetMemberInterfaces(bridge);
+               CFMutableArrayRef interfaceList;
+               
+               interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+               for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(bridgeMembers); idx2++) {
+                       CFStringRef interfaceName = NULL;
+                       SCNetworkInterfaceRef interface = NULL;
+                       
+                       interface = CFArrayGetValueAtIndex(bridgeMembers, idx2);
+                       interfaceName = SCNetworkInterfaceGetBSDName(interface);
+                       
+                       if (CFDictionaryContainsKey(bsdMapping, interfaceName) == TRUE) {
+                               CFStringRef bridgeNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bridge%ld"), count);
+                               CFDictionaryAddValue(bridgeMapping, interfaceName, bridgeNewName);
+                               CFArrayAppendValue(interfaceList, interfaceName);
+                               CFRelease(bridgeNewName);
+                               count++;
+                       }
+               }
+               if (CFArrayGetCount(interfaceList) > 0) {
+                       CFDictionaryAddValue(bridgeInterfaceMapping, bridge, interfaceList);
+               }
+               CFRelease(interfaceList);
+       }
+       // Remove bridge services from target
+       _SCNetworkMigrationRemoveBridgeServices(targetPrefs);
+       
+       // Remove Target Bridges
+       for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetBridges); idx++) {
+               bridge = CFArrayGetValueAtIndex(allTargetBridges, idx);
+               if (SCBridgeInterfaceRemove(bridge) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoBridgeMigration: Could not remove bridge: %@"), bridge);
+                       goto done;
+               }
+       }
+       
+       context.prefs = targetPrefs;
+       context.ni_prefs = targetNIPrefs;
+       context.bsdMapping = bsdMapping;
+       context.virtualBSDMapping = bridgeMapping;
+       context.mappingBSDNameToService = bsdNameToBridgeServices;
+       context.setMapping = setMapping;
+       context.serviceSetMapping = serviceSetMapping;
+       
+       // Add Bridge configurations at the target using mapping
+       CFDictionaryApplyFunction(bridgeInterfaceMapping, add_target_bridge, &context);
+       
+       success = TRUE;
+done:
+       CFRelease(allSourceBridges);
+       CFRelease(allTargetBridges);
+       CFRelease(bridgeInterfaceMapping);
+       CFRelease(bridgeMapping);
+       CFRelease(bsdNameToBridgeServices);
+       return success;
+}
+
+
+static void
+add_target_bond(const void *key, const void *value, void *context)
+{
+       CFNumberRef bondMode;
+       CFStringRef bondName;
+       CFDictionaryRef bondOptions;
+       SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
+       CFDictionaryRef bondBSDNameMapping = ctx->virtualBSDMapping;
+       CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
+       SCVirtualInterfaceMemberListContext memberListContext;
+       CFMutableArrayRef newInterfaceList;
+       SCBondInterfaceRef newBond;
+       SCBondInterfaceRef oldBond = (SCBondInterfaceRef)key;
+       CFStringRef oldBSDName;
+       CFArrayRef oldInterfaceList = (CFArrayRef)value;
+       CFArrayRef oldServiceList;
+       SCPreferencesRef prefs = ctx->prefs;
+       CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
+       CFDictionaryRef setMapping = ctx->setMapping;
+       
+       newInterfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       
+       memberListContext.bsdMapping = ctx->bsdMapping;
+       memberListContext.interfaceList = newInterfaceList;
+       memberListContext.ni_prefs = ctx->ni_prefs;
+       
+       CFArrayApplyFunction(oldInterfaceList, CFRangeMake(0, CFArrayGetCount(oldInterfaceList)), add_virtual_interface, &memberListContext);
+       
+       newBond = SCBondInterfaceCreate(prefs);
+       if (__SCBondInterfaceSetMemberInterfaces(newBond, newInterfaceList) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bond: Adding member interface failed."));
+       }
+       CFRelease(newInterfaceList);
+       
+       bondOptions = SCBondInterfaceGetOptions(oldBond);
+       if (bondOptions != NULL) {
+               SCBondInterfaceSetOptions(newBond, bondOptions);
+       }
+       
+       bondName = SCNetworkInterfaceGetLocalizedDisplayName(oldBond);
+       if (bondName != NULL) {
+               SCBondInterfaceSetLocalizedDisplayName(newBond, bondName);
+       }
+       
+       bondMode = SCBondInterfaceGetMode(oldBond);
+       if (bondMode != NULL) {
+               SCBondInterfaceSetMode(newBond, bondMode);
+       }
+       oldBSDName = SCNetworkInterfaceGetBSDName(oldBond);
+       if (oldBSDName == NULL) {
+               goto done;
+       }
+       
+       oldServiceList = CFDictionaryGetValue(bsdNameToServiceMapping, oldBSDName);
+       if (oldServiceList == NULL) {
+               goto done;
+       }
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
+               SCNetworkServiceRef oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
+               if (__SCNetworkServiceMigrateNew(prefs, oldService, bondBSDNameMapping, setMapping, serviceSetMapping) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_bond: Could not migrate service: %@"), oldService);
+               }
+       }
+done:
+       CFRelease(newBond);
+}
+
+static void
+_SCNetworkMigrationRemoveBondServices(SCPreferencesRef prefs)
+{
+       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
+               SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
+               CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
+               
+               if ((bsdName != NULL) &&
+               SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBond) {
+                       SCNetworkServiceRemove(service);
+               }
+       }
+       CFRelease(services);
+}
+
+
+static CFDictionaryRef
+_SCNetworkMigrationCopyMappingBSDNameToBondServices(SCPreferencesRef prefs)
+{
+       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
+       CFMutableDictionaryRef bondServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
+               SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
+               CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
+               
+               if ((bsdName != NULL) &&
+               SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeBond) {
+                       CFMutableArrayRef serviceList;
+                       if (CFDictionaryContainsKey(bondServices, bsdName) == FALSE) {
+                               serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                               CFDictionaryAddValue(bondServices, bsdName, serviceList);
+                               CFRelease(serviceList);
+                       }
+                       serviceList = (CFMutableArrayRef)CFDictionaryGetValue(bondServices, bsdName);
+                       CFArrayAppendValue(serviceList, service);
+               }
+       }
+       CFRelease(services);
+       return bondServices;
+}
+
+
+static Boolean
+_SCNetworkMigrationDoBondMigration (SCPreferencesRef sourcePrefs,
+                                   SCPreferencesRef sourceNIPrefs,
+                                   SCPreferencesRef targetPrefs,
+                                   SCPreferencesRef targetNIPrefs,
+                                   CFDictionaryRef bsdMapping,
+                                   CFDictionaryRef setMapping,
+                                   CFDictionaryRef serviceSetMapping)
+{
+       CFArrayRef allSourceBonds;
+       CFArrayRef allTargetBonds;
+       SCBondInterfaceRef bond;
+       CFMutableDictionaryRef bondInterfaceMapping = NULL;
+       CFMutableDictionaryRef bondMapping;
+       CFDictionaryRef bsdNameToBondServices;
+       SCVirtualInterfaceContext context;
+       CFIndex count = 0;
+       Boolean success = FALSE;
+       
+       allSourceBonds = SCBondInterfaceCopyAll(sourcePrefs);
+       allTargetBonds = SCBondInterfaceCopyAll(targetPrefs);
+       
+       bsdNameToBondServices = _SCNetworkMigrationCopyMappingBSDNameToBondServices(sourcePrefs);
+       
+       bondInterfaceMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       bondMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       // Create Bond Interface mapping
+       for (CFIndex idx = 0; idx < CFArrayGetCount(allSourceBonds); idx++) {
+               bond = CFArrayGetValueAtIndex(allSourceBonds, idx);
+               CFArrayRef bondMembers = SCBondInterfaceGetMemberInterfaces(bond);
+               CFMutableArrayRef interfaceList;
+               
+               interfaceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+               for (CFIndex idx2 = 0; idx2 < CFArrayGetCount(bondMembers); idx2++) {
+                       CFStringRef interfaceName;
+                       SCNetworkInterfaceRef interface;
+                       
+                       interface = CFArrayGetValueAtIndex(bondMembers, idx2);
+                       interfaceName = SCNetworkInterfaceGetBSDName(interface);
+                       
+                       if (CFDictionaryContainsKey(bsdMapping, interfaceName) == TRUE) {
+                               CFStringRef bondNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("bond%ld"), count);
+                               CFDictionaryAddValue(bondMapping, interfaceName, bondNewName);
+                               CFArrayAppendValue(interfaceList, interfaceName);
+                               CFRelease(bondNewName);
+                               count++;
+                       }
+               }
+               if (CFArrayGetCount(interfaceList) > 0) {
+                       CFDictionaryAddValue(bondInterfaceMapping, bond, interfaceList);
+               }
+               CFRelease(interfaceList);
+       }
+       // Remove bond services from target
+       _SCNetworkMigrationRemoveBondServices(targetPrefs);
+       
+       // Remove Target Bonds
+       for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetBonds); idx++) {
+               bond = CFArrayGetValueAtIndex(allTargetBonds, idx);
+               if (SCBondInterfaceRemove(bond) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoBondMigration: Could not remove bond: %@"), bond);
+                       goto done;
+               }
+       }
+       
+       context.prefs = targetPrefs;
+       context.ni_prefs = targetNIPrefs;
+       context.bsdMapping = bsdMapping;
+       context.virtualBSDMapping = bondMapping;
+       context.mappingBSDNameToService = bsdNameToBondServices;
+       context.setMapping = setMapping;
+       context.serviceSetMapping = serviceSetMapping;
+       
+       // Add Bond configurations at the target using mapping
+       CFDictionaryApplyFunction(bondInterfaceMapping, add_target_bond, &context);
+       
+       success = TRUE;
+done:
+       CFRelease(allSourceBonds);
+       CFRelease(allTargetBonds);
+       CFRelease(bondInterfaceMapping);
+       CFRelease(bondMapping);
+       CFRelease(bsdNameToBondServices);
+       return success;
+}
+
+static void
+add_target_vlan(const void *value, void *context)
+{
+       CFDictionaryRef bsdMapping;
+       SCVirtualInterfaceContext *ctx = (SCVirtualInterfaceContext*)context;
+       CFDictionaryRef bsdNameToServiceMapping = ctx->mappingBSDNameToService;
+       SCPreferencesRef prefs = ctx->prefs;
+       SCVLANInterfaceRef newVLAN = NULL;
+       SCNetworkInterfaceRef newPhysicalInterface = NULL;
+       CFStringRef newPhysicalInterfaceName;
+       SCVLANInterfaceRef oldVLAN = (SCVLANInterfaceRef)value;
+       CFStringRef oldBSDName;
+       SCNetworkInterfaceRef oldPhysicalInterface;
+       CFStringRef oldPhysicalInterfaceName;
+       SCNetworkServiceRef oldService;
+       CFArrayRef oldServiceList;
+       CFDictionaryRef serviceSetMapping = ctx->serviceSetMapping;
+       CFDictionaryRef setMapping = ctx->setMapping;
+       CFDictionaryRef vlanBSDMapping = ctx->virtualBSDMapping;
+       CFNumberRef vlanTag;
+       CFStringRef vlanName;
+       CFDictionaryRef vlanOptions;
+       
+       bsdMapping = ctx->bsdMapping;
+       oldPhysicalInterface = SCVLANInterfaceGetPhysicalInterface(oldVLAN);
+       
+       if (oldPhysicalInterface == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: oldPhysicalInterface is NULL"));
+               goto done;
+       }
+       oldPhysicalInterfaceName = SCNetworkInterfaceGetBSDName(oldPhysicalInterface);
+       
+       if (oldPhysicalInterfaceName == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: oldPhysicalInterfaceName is NULL"));
+               goto done;
+       }
+       
+       newPhysicalInterfaceName = CFDictionaryGetValue(bsdMapping, oldPhysicalInterfaceName);
+       if (newPhysicalInterfaceName == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: newPhysicalInterfaceName is NULL"));
+               goto done;
+       }
+       newPhysicalInterface = __SCNetworkInterfaceCreateWithNIPreferencesUsingBSDName(NULL, ctx->ni_prefs, newPhysicalInterfaceName);
+       if (newPhysicalInterface == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: newPhysicalInterface is NULL"));
+               goto done;
+       }
+       
+       vlanTag = SCVLANInterfaceGetTag(oldVLAN);
+       if (vlanTag == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: vlanTag is NULL"));
+               goto done;
+       }
+       
+       newVLAN = SCVLANInterfaceCreate(prefs, newPhysicalInterface, vlanTag);
+       if (newVLAN == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: Could not create newVLAN"));
+       }
+       
+       vlanName = SCNetworkInterfaceGetLocalizedDisplayName(oldVLAN);
+       if (vlanName != NULL) {
+               SCVLANInterfaceSetLocalizedDisplayName(newVLAN, vlanName);
+       }
+       
+       vlanOptions = SCVLANInterfaceGetOptions(oldVLAN);
+       if (vlanOptions != NULL) {
+               SCVLANInterfaceSetOptions(newVLAN, vlanOptions);
+       }
+       oldBSDName = SCNetworkInterfaceGetBSDName(oldVLAN);
+       
+       if (oldBSDName == NULL) {
+               goto done;
+       }
+       
+       oldServiceList = CFDictionaryGetValue(bsdNameToServiceMapping, oldBSDName);
+       if (oldServiceList == NULL) {
+               goto done;
+       }
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(oldServiceList); idx++) {
+               oldService = CFArrayGetValueAtIndex(oldServiceList, idx);
+               if (__SCNetworkServiceMigrateNew(prefs, oldService, vlanBSDMapping, setMapping, serviceSetMapping) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("add_target_vlan: Could not migrate service: %@"), oldService);
+               }
+       }
+       
+done:
+       if (newPhysicalInterface != NULL) {
+               CFRelease(newPhysicalInterface);
+       }
+       if (newVLAN != NULL) {
+               CFRelease(newVLAN);
+       }
+}
+
+static void
+_SCNetworkMigrationRemoveVLANServices(SCPreferencesRef prefs)
+{
+       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
+               SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
+               CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
+               
+               if ((bsdName != NULL) &&
+                   SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeVLAN) {
+                       SCNetworkServiceRemove(service);
+               }
+       }
+       
+       CFRelease(services);
+}
+
+
+static CFDictionaryRef
+_SCNetworkMigrationCopyMappingBSDNameToVLANServices(SCPreferencesRef prefs)
+{
+       CFArrayRef services = SCNetworkServiceCopyAll(prefs);
+       CFMutableDictionaryRef vlanServices = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(services); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(services, idx);
+               SCNetworkInterfaceRef interface = SCNetworkServiceGetInterface(service);
+               CFStringRef bsdName = SCNetworkInterfaceGetBSDName(interface);
+               
+               if ((bsdName != NULL) &&
+                   SCNetworkInterfaceGetInterfaceType(interface) == kSCNetworkInterfaceTypeVLAN) {
+                       CFMutableArrayRef serviceList;
+                       if (CFDictionaryContainsKey(vlanServices, bsdName) == FALSE) {
+                               serviceList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                               CFDictionaryAddValue(vlanServices, bsdName, serviceList);
+                               CFRelease(serviceList);
+                       }
+                       serviceList = (CFMutableArrayRef)CFDictionaryGetValue(vlanServices, bsdName);
+                       CFArrayAppendValue(serviceList, service);
+               }
+       }
+       CFRelease(services);
+       return vlanServices;
+}
+
+static Boolean
+_SCNetworkMigrationDoVLANMigration (SCPreferencesRef sourcePrefs,
+                                   SCPreferencesRef sourceNIPrefs,
+                                   SCPreferencesRef targetPrefs,
+                                   SCPreferencesRef targetNIPrefs,
+                                   CFDictionaryRef bsdMapping,
+                                   CFDictionaryRef setMapping,
+                                   CFDictionaryRef serviceSetMapping)
+{
+       CFArrayRef allSourceVLAN;
+       CFArrayRef allTargetVLAN;
+       SCVirtualInterfaceContext context;
+       CFIndex count = 0;
+       Boolean success = FALSE;
+       SCVLANInterfaceRef vlan;
+       CFMutableArrayRef vlanList;
+       CFMutableDictionaryRef vlanMapping;
+       CFDictionaryRef bsdNameToVLANServices;
+       
+       allSourceVLAN = SCVLANInterfaceCopyAll(sourcePrefs);
+       allTargetVLAN = SCVLANInterfaceCopyAll(targetPrefs);
+       
+       bsdNameToVLANServices = _SCNetworkMigrationCopyMappingBSDNameToVLANServices(sourcePrefs);
+       
+       vlanList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       vlanMapping = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(allSourceVLAN); idx++) {
+               vlan = CFArrayGetValueAtIndex(allSourceVLAN, idx);
+               CFStringRef vlanBSDName = SCNetworkInterfaceGetBSDName(vlan);
+               SCNetworkInterfaceRef physicalInterface = SCVLANInterfaceGetPhysicalInterface(vlan);
+               CFStringRef physicalInterfaceName;
+               
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVLANMigration: physical interface is %@"), physicalInterface);
+               
+               physicalInterfaceName = SCNetworkInterfaceGetBSDName(physicalInterface);
+                SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVLANMigration: Physical Interface name is %@"), physicalInterfaceName);
+                
+               // Add VLAN to be migrated if the mapping between interfaces exists
+               if (CFDictionaryContainsKey(bsdMapping, physicalInterfaceName) == TRUE) {
+                       CFStringRef vlanNewName = CFStringCreateWithFormat(NULL, NULL, CFSTR("vlan%ld"), count);
+                       CFDictionaryAddValue(vlanMapping, vlanBSDName, vlanNewName);
+                       CFArrayAppendValue(vlanList, vlan);
+                       CFRelease(vlanNewName);
+                       count++;
+               }
+       }
+       // Remove vlan services from target
+       _SCNetworkMigrationRemoveVLANServices(targetPrefs);
+       
+       // Remove Target VLANs
+       for (CFIndex idx = 0; idx < CFArrayGetCount(allTargetVLAN); idx++) {
+               vlan = CFArrayGetValueAtIndex(allTargetVLAN, idx);
+               if (SCVLANInterfaceRemove(vlan) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVLANMigration: Could not remove VLAN: %@"), vlan);
+                       goto done;
+               }
+       }
+       
+       context.prefs = targetPrefs;
+       context.ni_prefs = targetNIPrefs;
+       context.bsdMapping = bsdMapping;
+       context.virtualBSDMapping = vlanMapping;
+       context.mappingBSDNameToService = bsdNameToVLANServices;
+       context.setMapping = setMapping;
+       context.serviceSetMapping = serviceSetMapping;
+       
+       // Add VLAN configurations at the target using vlanList
+       CFArrayApplyFunction(vlanList, CFRangeMake(0, CFArrayGetCount(vlanList)), add_target_vlan, &context);
+       
+       success = TRUE;
+done:
+       CFRelease(allSourceVLAN);
+       CFRelease(allTargetVLAN);
+       CFRelease(vlanList);
+       CFRelease(vlanMapping);
+       CFRelease(bsdNameToVLANServices);
+       return success;
+}
+
+static Boolean
+_SCNetworkMigrationDoVirtualNetworkInterfaceMigration(SCPreferencesRef sourcePrefs,
+                                                     SCPreferencesRef sourceNIPrefs,
+                                                     SCPreferencesRef targetPrefs,
+                                                     SCPreferencesRef targetNIPrefs,
+                                                     CFDictionaryRef bsdMapping,
+                                                     CFDictionaryRef setMapping,
+                                                     CFDictionaryRef serviceSetMapping)
+{
+       // Handle Bridges
+       if (_SCNetworkMigrationDoBridgeMigration(sourcePrefs, sourceNIPrefs,
+                                                targetPrefs, targetNIPrefs,
+                                                bsdMapping, setMapping, serviceSetMapping) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVirtualNetworkInterfaceMigration: Bridge migration failed"));
+       }
+       
+       // Handle Bonds
+       if (_SCNetworkMigrationDoBondMigration(sourcePrefs, sourceNIPrefs,
+                                              targetPrefs, targetNIPrefs,
+                                              bsdMapping, setMapping, serviceSetMapping) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVirtualNetworkInterfaceMigration: Bond migration failed"));
+       }
+       
+       // Handle VLANs
+       if (_SCNetworkMigrationDoVLANMigration(sourcePrefs, sourceNIPrefs,
+                                              targetPrefs, targetNIPrefs,
+                                              bsdMapping, setMapping, serviceSetMapping) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationDoVirtualNetworkInterfaceMigration: VLAN migration failed"));
+       }
+       return TRUE;
+}
+#endif
+
+typedef struct {
+       SCPreferencesRef prefs;
+       CFArrayRef serviceOrder;
+       CFMutableArrayRef serviceListMutable;
+       Boolean* success;
+} migrated_service_context;
+
+static void
+create_migrated_order(const void *value, void *context)
+{
+       migrated_service_context *ctx = (migrated_service_context*)context;
+       CFMutableArrayRef migratedServiceOrder = ctx->serviceListMutable;
+       CFArrayRef targetServiceOrder = ctx->serviceOrder;
+       CFStringRef migratedServiceID = (CFStringRef)value;
+       Boolean *success = ctx->success;
+       
+       if (*success == FALSE) {
+               return;
+       }
+       // Preserving the service order in the source configuration for the services
+       // which were migrated into the target configuration
+       for (CFIndex idx = 0; idx < CFArrayGetCount(targetServiceOrder); idx++) {
+               CFStringRef targetServiceID = CFArrayGetValueAtIndex(targetServiceOrder, idx);
+               if (CFEqual(migratedServiceID, targetServiceID) == TRUE) {
+                       CFArrayAppendValue(migratedServiceOrder, migratedServiceID);
+                       return;
+               }
+       }
+}
+
+static void
+create_non_migrated_service_list(const void *value, void *context)
+{
+       migrated_service_context *ctx = (migrated_service_context*)context;
+       CFArrayRef migratedServiceOrder = ctx->serviceOrder;
+       CFMutableArrayRef nonMigratedService = ctx->serviceListMutable;
+       SCPreferencesRef prefs = ctx->prefs;
+       SCNetworkServiceRef service;
+       Boolean *success = ctx->success;
+       CFStringRef targetServiceID = (CFStringRef)value;
+       
+       if (*success == FALSE) {
+               return;
+       }
+       // Adding all services not present in migratedServiceOrder into nonMigrated service
+       for (CFIndex idx = 0; idx < CFArrayGetCount(migratedServiceOrder); idx++) {
+               CFStringRef migratedServiceID = CFArrayGetValueAtIndex(migratedServiceOrder, idx);
+               
+               if (CFEqual(targetServiceID, migratedServiceID) == TRUE) {
+                       return;
+               }
+       }
+       service = SCNetworkServiceCopy(prefs, targetServiceID);
+       if (service == NULL) {
+               *success = FALSE;
+               return;
+       }
+       
+       CFArrayAppendValue(nonMigratedService, service);
+       CFRelease(service);
+}
+
+static void
+preserve_service_order(const void *key, const void *value, void *context)
+{
+       migrated_service_context migrated_context;
+       CFMutableArrayRef migratedServiceOrder;
+       migrated_service_context non_migrated_context;
+       CFMutableArrayRef nonMigratedServices;
+       SCNetworkSetRef sourceSet = (SCNetworkSetRef)key;
+       CFArrayRef sourceServiceOrder = NULL;
+       Boolean *success = (Boolean*)context;
+       SCNetworkSetRef targetSet = (SCNetworkSetRef)value;
+       SCNetworkSetPrivateRef targetPrivate = (SCNetworkSetPrivateRef)targetSet;
+       CFArrayRef targetServiceOrder = NULL;
+       
+       if (*success == FALSE) {
+               return;
+       }
+       migratedServiceOrder = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       nonMigratedServices = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       
+       sourceServiceOrder = SCNetworkSetGetServiceOrder(sourceSet);
+       if (sourceServiceOrder == NULL) {
+               goto done;
+       }
+       targetServiceOrder = SCNetworkSetGetServiceOrder(targetSet);
+       if (targetServiceOrder == NULL) {
+               goto done;
+       }
+       
+       migrated_context.prefs = NULL;
+       migrated_context.serviceOrder = targetServiceOrder;
+       migrated_context.serviceListMutable = migratedServiceOrder;
+       migrated_context.success = success;
+       
+       // Creating a list of service IDs which were migrated in the target set
+       // while maintaining the service order or the source set
+       CFArrayApplyFunction(sourceServiceOrder, CFRangeMake(0, CFArrayGetCount(sourceServiceOrder)), create_migrated_order, &migrated_context);
+       
+       if (success == FALSE) {
+               goto done;
+       }
+       
+       non_migrated_context.prefs = targetPrivate->prefs;
+       non_migrated_context.serviceOrder = migratedServiceOrder;
+       non_migrated_context.serviceListMutable = nonMigratedServices;
+       non_migrated_context.success = success;
+       
+       // Creating a list of all the services which were not migrated from the source set to the
+       // target set
+       CFArrayApplyFunction(targetServiceOrder, CFRangeMake(0, CFArrayGetCount(targetServiceOrder)), create_non_migrated_service_list, &non_migrated_context);
+       
+       // Remove non migrated service
+       for (CFIndex idx = 0; idx < CFArrayGetCount(nonMigratedServices); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
+               SCNetworkSetRemoveService(targetSet, service);
+       }
+       // Set migrated service order
+       SCNetworkSetSetServiceOrder(targetSet, migratedServiceOrder);
+       
+       // Add non migrated services
+       for (CFIndex idx = 0; idx < CFArrayGetCount(nonMigratedServices); idx++) {
+               SCNetworkServiceRef service = CFArrayGetValueAtIndex(nonMigratedServices, idx);
+               SCNetworkSetAddService(targetSet, service);
+       }
+       
+done:
+       CFRelease(migratedServiceOrder);
+       CFRelease(nonMigratedServices);
+       return;
+       
+}
+
+static Boolean
+_SCNetworkMigrationDoServiceOrderMigration(SCPreferencesRef sourcePrefs,
+                                          SCPreferencesRef targetPrefs,
+                                          CFDictionaryRef setMapping)
+{
+       Boolean success = TRUE;
+       
+       if (isA_CFDictionary(setMapping) == NULL) {
+               success = FALSE;
+               goto done;
+       }
+       
+       CFDictionaryApplyFunction(setMapping, preserve_service_order, &success);
+done:
+       return success;
+}
+
+
+// This is a function that looks at source and target network configuration
+// and determines what network configurations can be transferred from source to
+// target
+static Boolean
+_SCNetworkConfigurationMigrateConfiguration(CFURLRef sourceDir, CFURLRef targetDir)
+{
+       CFDictionaryRef bsdNameMapping = NULL;              // Mapping between BSD name and SCNetworkInterfaceRef to help with mapping services
+       CFMutableDictionaryRef builtinMapping = NULL;       // Mapping between builtin interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
+       CFMutableDictionaryRef externalMapping = NULL;      // Mapping between external interfaces between source and target configurations: (SCNetworkInterfaceRef -> SCNetworkInterfaceRef)
+       Boolean migrationSuccess = FALSE;
+       CFArrayRef newTargetNetworkInterfaceEntity = NULL;  // Array of Interface Entity which used to create new target interfaces created during migration
+       CFDictionaryRef serviceMapping = NULL;              // Mapping between services of source to target. (SCNetworkServicesRef -> SCNetworkServicesRef)
+       CFDictionaryRef setMapping = NULL;
+       CFDictionaryRef sourceServiceSetMapping = NULL;
+       CFArrayRef sourceConfigurationFiles = NULL;                                                     // Path to the source configuration files which need to be migrated
+       CFURLRef sourceNetworkInterfaceFile = NULL;                     // Source CFURLRef for preferences.plist and NetworkInterfaces.plist
+       char sourceNetworkInterfaceFileStr[PATH_MAX];
+       CFStringRef sourceNetworkInterfaceFileString = NULL;    // Source CFStringRef for preferences.plist and NetworkInterfaces.plist
+       SCPreferencesRef sourceNetworkInterfacePrefs = NULL;                    // Source SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
+       CFURLRef sourcePreferencesFile = NULL;
+       char sourcePreferencesFileStr[PATH_MAX];
+       CFStringRef sourcePreferencesFileString = NULL;
+       SCPreferencesRef sourcePrefs = NULL;
+       CFArrayRef targetConfigurationFiles = NULL;                                                     // Path to the target configuration files where migration will take place to
+       Boolean targetConfigurationFilesPresent;
+       CFURLRef targetNetworkInterfaceFile = NULL;                     // Target CFURLRef for preferences.plist and NetworkInterfaces.plist
+       char targetNetworkInterfaceFileStr[PATH_MAX];
+       CFStringRef targetNetworkInterfaceFileString = NULL;    // Target CFStringRef for preferences.plist and NetworkInterfaces.plist
+       SCPreferencesRef targetNetworkInterfacePrefs = NULL;                    // Target SCPreferencesRef for preferences.plist and NetworkInterfaces.plist
+       CFURLRef targetPreferencesFile = NULL;
+       char targetPreferencesFileStr[PATH_MAX];
+       CFStringRef targetPreferencesFileString = NULL;
+       SCPreferencesRef targetPrefs = NULL;
+       CFMutableDictionaryRef validityOptions = NULL;
+
+       // Check if configuration files exist in sourceDir
+       if (__SCNetworkConfigurationMigrateConfigurationFilesPresent(sourceDir, &sourceConfigurationFiles) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: sourceDir: (%@) doesn't contain configuration files"), sourceDir);
+               goto done;
+       }
+
+       sourcePreferencesFile = CFArrayGetValueAtIndex(sourceConfigurationFiles, PREFERENCES_PLIST_INDEX);
+       if (CFURLGetFileSystemRepresentation(sourcePreferencesFile, TRUE, (UInt8*)sourcePreferencesFileStr, sizeof(sourcePreferencesFileStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), sourcePreferencesFile);
+               goto done;
+       }
+
+       sourceNetworkInterfaceFile = CFArrayGetValueAtIndex(sourceConfigurationFiles, NETWORK_INTERFACES_PLIST_INDEX);
+       if (CFURLGetFileSystemRepresentation(sourceNetworkInterfaceFile, TRUE, (UInt8*)sourceNetworkInterfaceFileStr, sizeof(sourceNetworkInterfaceFileStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), sourceNetworkInterfaceFile);
+               goto done;
+       }
+
+       sourcePreferencesFileString = CFStringCreateWithCString(NULL, sourcePreferencesFileStr, kCFStringEncodingUTF8);
+       sourceNetworkInterfaceFileString = CFStringCreateWithCString(NULL, sourceNetworkInterfaceFileStr, kCFStringEncodingUTF8);
+
+       sourcePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, sourcePreferencesFileString);
+       sourceNetworkInterfacePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, sourceNetworkInterfaceFileString);
+       if ((sourcePrefs == NULL) || (sourceNetworkInterfacePrefs == NULL)) {
+               goto done;
+       }
+       
+       if ((targetConfigurationFilesPresent = __SCNetworkConfigurationMigrateConfigurationFilesPresent(targetDir, &targetConfigurationFiles)) == FALSE) {
+               if (targetConfigurationFiles == NULL) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: targetConfigurationFiles is NULL"));
+                       goto done;
+               }
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: targetDir: (%@) doesn't contain configuration files ... Need to create default configuration"), targetDir);
+       }
+       
+       targetPreferencesFile = CFArrayGetValueAtIndex(targetConfigurationFiles, PREFERENCES_PLIST_INDEX);
+       if (CFURLGetFileSystemRepresentation(targetPreferencesFile, TRUE, (UInt8*)targetPreferencesFileStr, sizeof(targetPreferencesFileStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), targetPreferencesFile);
+               goto done;
+       }
+       targetNetworkInterfaceFile = CFArrayGetValueAtIndex(targetConfigurationFiles, NETWORK_INTERFACES_PLIST_INDEX);
+       if (CFURLGetFileSystemRepresentation(targetNetworkInterfaceFile, TRUE, (UInt8*)targetNetworkInterfaceFileStr, sizeof(targetNetworkInterfaceFileStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Cannot get file system representation for url: %@"), targetNetworkInterfaceFile);
+               goto done;
+       }
+
+       targetPreferencesFileString = CFStringCreateWithCString(NULL, targetPreferencesFileStr, kCFStringEncodingUTF8);
+       targetNetworkInterfaceFileString = CFStringCreateWithCString(NULL, targetNetworkInterfaceFileStr, kCFStringEncodingUTF8);
+
+       if (targetConfigurationFilesPresent == TRUE) {
+               targetPrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetPreferencesFileString);
+               targetNetworkInterfacePrefs = SCPreferencesCreate(NULL, PLUGIN_ID, targetNetworkInterfaceFileString);
+               if ((targetPrefs == NULL) || (targetNetworkInterfacePrefs == NULL)) {
+                       goto done;
+               }
+       }
+       else {
+               targetPrefs = __SCNetworkCreateDefaultPref(targetPreferencesFileString);
+               targetNetworkInterfacePrefs = __SCNetworkCreateDefaultNIPrefs(targetNetworkInterfaceFileString);
+               
+               if (targetPrefs == NULL ||
+                   targetNetworkInterfacePrefs == NULL) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Could not create default configuration."));
+                       goto done;
+               }
+       }
+       validityOptions = CFDictionaryCreateMutable(NULL, 0,
+                                                   &kCFTypeDictionaryKeyCallBacks,
+                                                   &kCFTypeDictionaryValueCallBacks);
+       CFDictionaryAddValue(validityOptions, kSCNetworkConfigurationRepair, kCFBooleanTrue);
+       
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("sourcePreferenceFileString: %@\n sourceNetworkInterfaceFileString:%@\n targetPreferencesFileString:%@\ntargetNetworkInterfaceFileString:%@"), sourcePreferencesFileString, sourceNetworkInterfaceFileString,
+             targetPreferencesFileString, targetNetworkInterfaceFileString);
+
+       // Setting Bypass Interface to avoid looking at system interfaces
+       __SCPreferencesSetLimitSCNetworkConfiguration(sourcePrefs, TRUE);
+       __SCPreferencesSetLimitSCNetworkConfiguration(targetPrefs, TRUE);
+
+       // Create services for builtin interfaces at source if they don't exist
+       (void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(sourcePrefs, sourceNetworkInterfacePrefs);
+       // Checking validity of the source and destination preferences before continuing
+       if (_SCNetworkConfigurationCheckValidityUsingPreferences(sourcePrefs,
+                                                                sourceNetworkInterfacePrefs,
+                                                                validityOptions) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Source configuration is not valid"));
+               goto skipServiceMigration;
+       }
+       // Only call this function if configuration files were not created by default
+       if (targetConfigurationFilesPresent == TRUE) {
+               // Create services for builtin interfaces at target if they don't exist
+               (void)_SCNetworkConfigurationCreateBuiltinInterfaceServices(targetPrefs, targetNetworkInterfacePrefs);
+               if (_SCNetworkConfigurationCheckValidityUsingPreferences(targetPrefs,
+                                                                        targetNetworkInterfacePrefs,
+                                                                        validityOptions) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Target configuration is not valid"));
+                       goto skipServiceMigration;
+               }
+       }
+
+       builtinMapping = _SCNetworkConfigurationCopyBuiltinMapping(sourceNetworkInterfacePrefs, targetNetworkInterfacePrefs);
+       externalMapping = _SCNetworkConfigurationCopyExternalInterfaceMapping(sourceNetworkInterfacePrefs, targetNetworkInterfacePrefs);
+
+       /*
+        TODO:
+        Now builtin and external interface mapping is complete, work needs to be done on updating the preferences.plist and NetworkInterface.plist.
+
+        Also, work needs to be done to check the validity of the data in preferences in source and target destinations, and after migration
+        */
+
+       newTargetNetworkInterfaceEntity = _SCNetworkMigrationCreateNetworkInterfaceArray(targetNetworkInterfacePrefs, externalMapping);
+       if (isA_CFArray(newTargetNetworkInterfaceEntity) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: newTargetNetworkInterfaceEntity is NULL or not of correct type"));
+               goto done;
+       }
+       // Write new interface mapping to NetworkInterfaces.plist
+       if (__SCNetworkInterfaceSaveStoredWithPreferences(targetNetworkInterfacePrefs, newTargetNetworkInterfaceEntity) == FALSE)
+       {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: SCNetworkInterfaceSaveStoreWithPreferences failed to update NetworkInterface.plist"));
+               goto done;
+       }
+       // Create BSD Name Mapping to facilitate mapping of services
+       bsdNameMapping = _SCNetworkMigrationCreateBSDNameMapping(builtinMapping, externalMapping);
+
+       if (isA_CFDictionary(bsdNameMapping) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: BSD Name Mapping is NULL"));
+               goto done;
+       }
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("BSD Name Mapping: %@"), bsdNameMapping);
+       serviceMapping = _SCNetworkMigrationCreateServiceMappingUsingBSDMapping(sourcePrefs, targetPrefs, bsdNameMapping);
+
+       if (isA_CFDictionary(serviceMapping) == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Service Mapping is NULL"));
+               goto done;
+       }
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("Service Mapping: %@"), serviceMapping);
+
+       setMapping = _SCNetworkMigrationCreateSetMapping(sourcePrefs, targetPrefs);
+       sourceServiceSetMapping = _SCNetworkMigrationCreateServiceSetMapping(sourcePrefs);
+       
+       // Perform the migration of services
+       if (_SCNetworkMigrationDoServiceMigration(sourcePrefs, targetPrefs,
+                                                 serviceMapping, bsdNameMapping,
+                                                 setMapping, sourceServiceSetMapping) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: SCNetworkMigrationDoServiceMigration failed to complete successfully"));
+               goto done;
+       }
+       
+#if    !TARGET_OS_IPHONE
+       // Migrating Virtual Network Interface
+       if (_SCNetworkMigrationDoVirtualNetworkInterfaceMigration(sourcePrefs, sourceNetworkInterfacePrefs,
+                                                                 targetPrefs, targetNetworkInterfacePrefs,
+                                                                 bsdNameMapping, setMapping, sourceServiceSetMapping) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: _SCNetworkMigrationDoVirtualNetworkInterfaceMigration failed to complete successfully"));
+       }
+#endif
+       // Migrate Service Order
+       if (_SCNetworkMigrationDoServiceOrderMigration(sourcePrefs, targetPrefs, setMapping) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: _SCNetworkMigrationDoServiceOrderMigration failed to complete successfully"));
+       }
+       
+skipServiceMigration:
+       // Migrating System Information
+       if (_SCNetworkMigrationDoSystemMigration(sourcePrefs, targetPrefs) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: _SCNetworkMigrationDoSystemMigration failed to complete successfully"));
+       }
+
+       if (_SCNetworkConfigurationCheckValidityUsingPreferences(targetPrefs, targetNetworkInterfacePrefs, NULL) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Migrated configuration is not valid"));
+               goto done;
+       }
+       if (SCPreferencesCommitChanges(targetPrefs) == FALSE) {
+               SCLog(TRUE, LOG_ERR, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Error commiting targetPrefs, %s"), SCErrorString(SCError()));
+               goto done;
+       }
+
+       if (SCPreferencesCommitChanges(targetNetworkInterfacePrefs) == FALSE) {
+               SCLog(TRUE, LOG_ERR, CFSTR("_SCNetworkConfigurationMigrateConfiguration: Error commiting targetNetworkInterfacePrefs, %s"), SCErrorString(SCError()));
+               goto done;
+       }
+       migrationSuccess = TRUE;
+
+done:
+       if (setMapping != NULL) {
+               CFRelease(setMapping);
+       }
+       if (sourceServiceSetMapping != NULL) {
+               CFRelease(sourceServiceSetMapping);
+       }
+       if (sourceConfigurationFiles != NULL) {
+               CFRelease(sourceConfigurationFiles);
+       }
+       if (targetConfigurationFiles != NULL) {
+               CFRelease(targetConfigurationFiles);
+       }
+       if (sourcePreferencesFileString != NULL) {
+               CFRelease(sourcePreferencesFileString);
+       }
+       if (sourceNetworkInterfaceFileString != NULL) {
+               CFRelease(sourceNetworkInterfaceFileString);
+       }
+       if (targetPreferencesFileString != NULL) {
+               CFRelease(targetPreferencesFileString);
+       }
+       if (targetNetworkInterfaceFileString != NULL) {
+               CFRelease(targetNetworkInterfaceFileString);
+       }
+       if (newTargetNetworkInterfaceEntity != NULL) {
+               CFRelease(newTargetNetworkInterfaceEntity);
+       }
+       if (builtinMapping != NULL) {
+               CFRelease(builtinMapping);
+       }
+       if (externalMapping != NULL) {
+               CFRelease(externalMapping);
+       }
+       if (bsdNameMapping != NULL) {
+               CFRelease(bsdNameMapping);
+       }
+       if (serviceMapping != NULL) {
+               CFRelease(serviceMapping);
+       }
+       if (targetPrefs != NULL) {
+               CFRelease(targetPrefs);
+       }
+       if (sourcePrefs != NULL) {
+               CFRelease(sourcePrefs);
+       }
+       if (sourceNetworkInterfacePrefs != NULL) {
+               CFRelease(sourceNetworkInterfacePrefs);
+       }
+       if (targetNetworkInterfacePrefs != NULL) {
+               CFRelease(targetNetworkInterfacePrefs);
+       }
+       if (validityOptions != NULL) {
+               CFRelease(validityOptions);
+       }
+       return migrationSuccess;
+}
+
+#define N_QUICK 64
+
+static Boolean
+_SCNetworkMigrationAreServicesIdentical( SCPreferencesRef configPref, SCPreferencesRef expectedConfigPref)
+{
+       const void * expected_vals_q[N_QUICK];
+       const void ** expected_vals = expected_vals_q;
+       CFMutableArrayRef expectedServiceArray = NULL;
+       CFIndex expectedServiceArrayCount = 0;
+       CFDictionaryRef expectedServiceDict = NULL;
+       CFIndex expectedServiceDictCount = 0;
+       CFDictionaryRef expectedServiceEntity = 0;
+       Boolean foundMatch = FALSE;
+       CFMutableArrayRef serviceArray = NULL;
+       CFIndex serviceArrayCount = 0;
+       CFDictionaryRef serviceDict = NULL;
+       CFIndex serviceDictCount = 0;
+       CFDictionaryRef serviceEntity = NULL;
+       Boolean success = FALSE;
+       const void * vals_q[N_QUICK];
+       const void ** vals = vals_q;
+
+       serviceDict = SCPreferencesGetValue(configPref, kSCPrefNetworkServices);
+       if (isA_CFDictionary(serviceDict) == NULL) {
+               goto done;
+       }
+       serviceDictCount = CFDictionaryGetCount(serviceDict);
+
+       expectedServiceDict = SCPreferencesGetValue(expectedConfigPref, kSCPrefNetworkServices);
+       if (isA_CFDictionary(expectedServiceDict) == NULL) {
+               goto done;
+       }
+       expectedServiceDictCount = CFDictionaryGetCount(expectedServiceDict);
+
+       if (serviceDictCount != expectedServiceDictCount) {
+               goto done;
+       }
+
+       if (serviceDictCount > (sizeof(vals_q) / sizeof(CFTypeRef))) {
+               vals = CFAllocatorAllocate(NULL, serviceDictCount * sizeof(CFPropertyListRef), 0);
+       }
+
+       CFDictionaryGetKeysAndValues(serviceDict, NULL, vals);
+       serviceArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       for (CFIndex idx=0; idx < serviceDictCount; idx++) {
+               serviceEntity = vals[idx];
+               if (isA_CFDictionary(serviceEntity) == FALSE) {
+                       continue;
+               }
+               CFArrayAppendValue(serviceArray, serviceEntity);
+       }
+
+       serviceArrayCount = CFArrayGetCount(serviceArray);
+
+       if (expectedServiceDictCount > (sizeof(expected_vals_q) / sizeof(CFTypeRef))) {
+               expected_vals = CFAllocatorAllocate(NULL, expectedServiceDictCount, 0);
+       }
+
+       CFDictionaryGetKeysAndValues(expectedServiceDict, NULL, expected_vals);
+       expectedServiceArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+       for (CFIndex idx = 0; idx < expectedServiceDictCount; idx++) {
+               serviceEntity = expected_vals[idx];
+
+               if (isA_CFDictionary(serviceEntity) == FALSE) {
+                       continue;
+               }
+               CFArrayAppendValue(expectedServiceArray, serviceEntity);
+       }
+       expectedServiceArrayCount = CFArrayGetCount(expectedServiceArray);
+
+       if (serviceArrayCount != expectedServiceArrayCount) {
+               goto done;
+       }
+
+       for (CFIndex idx = 0; idx < expectedServiceArrayCount; idx++) {
+               foundMatch = FALSE;
+               expectedServiceEntity = CFArrayGetValueAtIndex(expectedServiceArray, idx);
+               serviceArrayCount = CFArrayGetCount(serviceArray);
+
+               for (CFIndex idx2 = 0; idx2 < serviceArrayCount; idx2++) {
+                       serviceEntity = CFArrayGetValueAtIndex(serviceArray, idx2);
+
+                       if (CFEqual(expectedServiceEntity, serviceEntity) == TRUE) {
+                               foundMatch = TRUE;
+                               break;
+                       }
+               }
+
+               if (foundMatch == FALSE) {
+                       break;
+               }
+       }
+
+       success = foundMatch;
+done:
+       if (vals != vals_q) {
+               CFAllocatorDeallocate(NULL, vals);
+       }
+       if (expected_vals != expected_vals_q) {
+               CFAllocatorDeallocate(NULL, expected_vals);
+       }
+       return success;
+}
+
+static Boolean
+_SCNetworkMigrationAreNetworkInterfaceConfigurationsIdentical (SCPreferencesRef configNetworkInterfacePref, SCPreferencesRef expectedNetworkInterfacePref)
+{
+       CFDictionaryRef expectedInterfaceEntity = NULL;
+       CFArrayRef expectedInterfaceList = NULL;
+       CFIndex expectedInterfaceListCount;
+       Boolean foundMatch = FALSE;
+       CFDictionaryRef interfaceEntity = NULL;
+       CFArrayRef interfaceList = NULL;
+       CFIndex interfaceListCount;
+       CFMutableArrayRef interfaceListMutable = NULL;
+       Boolean success = FALSE;
+
+       interfaceList = SCPreferencesGetValue(configNetworkInterfacePref, INTERFACES);
+       if (isA_CFArray(interfaceList) == NULL) {
+               goto done;
+       }
+       interfaceListMutable = CFArrayCreateMutableCopy(NULL, 0, interfaceList);
+       interfaceListCount = CFArrayGetCount(interfaceListMutable);
+
+       expectedInterfaceList = SCPreferencesGetValue(expectedNetworkInterfacePref, INTERFACES);
+       if (isA_CFArray(expectedInterfaceList) == NULL) {
+               goto done;
+       }
+       expectedInterfaceListCount = CFArrayGetCount(expectedInterfaceList);
+
+       if (interfaceListCount != expectedInterfaceListCount) {
+               goto done;
+       }
+
+       for (CFIndex idx = 0; idx < expectedInterfaceListCount; idx++) {
+               foundMatch = FALSE;
+               expectedInterfaceEntity = CFArrayGetValueAtIndex(expectedInterfaceList, idx);
+               interfaceListCount = CFArrayGetCount(interfaceListMutable);
+
+               for (CFIndex idx2 = 0; idx2 < interfaceListCount; idx2++) {
+                       interfaceEntity = CFArrayGetValueAtIndex(interfaceList, idx2);
+                       if (CFEqual(expectedInterfaceEntity, interfaceEntity) == TRUE) {
+                               foundMatch = TRUE;
+                               break;
+                       }
+               }
+               if (foundMatch == FALSE) {
+                       break;
+               }
+       }
+       success = foundMatch;
+
+done:
+       if (interfaceListMutable != NULL) {
+               CFRelease(interfaceListMutable);
+       }
+
+       return success;
+}
+
+Boolean
+_SCNetworkMigrationAreConfigurationsIdentical (CFURLRef configurationURL,
+                                              CFURLRef expectedConfigurationURL)
+{
+       CFURLRef baseConfigURL = NULL;
+       CFURLRef baseExpectedConfigURL = NULL;
+       CFURLRef configPreferencesURL = NULL;
+       CFURLRef configNetworkInterfacesURL = NULL;
+       SCPreferencesRef configPref = NULL;
+       SCPreferencesRef configNetworkInterfacePref = NULL;
+       SCPreferencesRef expectedConfigPref = NULL;
+       SCPreferencesRef expectedNetworkInterfacePref = NULL;
+       CFURLRef expectedNetworkInterfaceURL = NULL;
+       CFURLRef expectedPreferencesURL = NULL;
+       Boolean isIdentical = FALSE;
+       CFStringRef networkInterfaceConfigString = NULL;
+       CFStringRef networkInterfaceExpectedString = NULL;
+       CFStringRef prefsConfigString = NULL;
+       CFStringRef prefsExpectedString = NULL;
+       char networkInterfaceConfigStr[PATH_MAX];
+       char networkInterfaceExpectedStr[PATH_MAX];
+       char prefsConfigStr[PATH_MAX];
+       char prefsExpectedStr[PATH_MAX];
+       
+       if (configurationURL == NULL ||
+           expectedConfigurationURL == NULL) {
+               return FALSE;
+       }
+       baseConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, configurationURL);
+       configPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*) PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseConfigURL);
+        
+        if (CFURLResourceIsReachable(configPreferencesURL, NULL) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: preferences.plist file is not present."));
+               goto done;
+        }
+       
+       configNetworkInterfacesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseConfigURL);
+       
+       if (CFURLResourceIsReachable(configNetworkInterfacesURL, NULL) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: NetworkInterfaces.plist file is not present."));
+               goto done;
+       }
+       
+       if (CFURLGetFileSystemRepresentation(configPreferencesURL, TRUE, (UInt8*)prefsConfigStr, sizeof(prefsConfigStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract preferences information"));
+               goto done;
+       }
+       if (CFURLGetFileSystemRepresentation(configNetworkInterfacesURL, TRUE, (UInt8*)networkInterfaceConfigStr, sizeof(networkInterfaceConfigStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract network interfaces information"));
+               goto done;
+       }
+       
+       baseExpectedConfigURL = CFURLCreateWithFileSystemPathRelativeToBase(NULL, PREFS_DEFAULT_DIR_RELATIVE, kCFURLPOSIXPathStyle, TRUE, expectedConfigurationURL);
+       expectedPreferencesURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)PREFS_DEFAULT_CONFIG_PLIST, sizeof(PREFS_DEFAULT_CONFIG_PLIST), FALSE, baseExpectedConfigURL);
+       
+       if (CFURLResourceIsReachable(expectedPreferencesURL, NULL) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: preferences.plist file is not present in the expected configuration."));
+               goto done;
+       }
+       
+       expectedNetworkInterfaceURL = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)NETWORK_INTERFACES_PREFS_PLIST, sizeof(NETWORK_INTERFACES_PREFS_PLIST), FALSE, baseExpectedConfigURL);
+       
+       if (CFURLResourceIsReachable(expectedNetworkInterfaceURL, NULL) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: NetworkInterfaces.plist file is not present in the expected configuration."));
+               goto done;
+       }
+       
+       if (CFURLGetFileSystemRepresentation(expectedPreferencesURL, TRUE, (UInt8*)prefsExpectedStr, sizeof(prefsExpectedStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract preferences information"));
+               goto done;
+       }
+       if (CFURLGetFileSystemRepresentation(expectedNetworkInterfaceURL, TRUE, (UInt8*)networkInterfaceExpectedStr, sizeof(networkInterfaceExpectedStr)) == FALSE) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: Could not extract network interfaces information"));
+               goto done;
+       }
+       
+       prefsConfigString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), prefsConfigStr);
+       networkInterfaceConfigString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), networkInterfaceConfigStr);
+       prefsExpectedString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), prefsExpectedStr);
+       networkInterfaceExpectedString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%s"), networkInterfaceExpectedStr);
+       
+       configPref = SCPreferencesCreate(NULL, PLUGIN_ID, prefsConfigString);
+       expectedConfigPref = SCPreferencesCreate(NULL, PLUGIN_ID, prefsExpectedString);
+       configNetworkInterfacePref = SCPreferencesCreate(NULL, PLUGIN_ID, networkInterfaceConfigString);
+       expectedNetworkInterfacePref = SCPreferencesCreate(NULL, PLUGIN_ID, networkInterfaceExpectedString);
+done:
+       if (configPref == NULL ||
+           expectedConfigPref == NULL ||
+           configNetworkInterfacePref == NULL ||
+           expectedNetworkInterfacePref == NULL) {
+               SCLog(_sc_debug, LOG_NOTICE, CFSTR("_SCNetworkMigrationAreConfigurationsIdentical: One of the preferences is NULL"));
+               isIdentical = FALSE;
+       }
+       else {
+               isIdentical = (_SCNetworkMigrationAreServicesIdentical(configPref, expectedConfigPref) &&
+                              _SCNetworkMigrationAreNetworkInterfaceConfigurationsIdentical(configNetworkInterfacePref, expectedNetworkInterfacePref));
+       }
+       if (baseConfigURL != NULL) {
+               CFRelease(baseConfigURL);
+       }
+       if (configPreferencesURL != NULL) {
+               CFRelease(configPreferencesURL);
+       }
+       if (configNetworkInterfacesURL != NULL) {
+               CFRelease(configNetworkInterfacesURL);
+       }
+       if (baseExpectedConfigURL != NULL) {
+               CFRelease(baseExpectedConfigURL);
+       }
+       if (expectedPreferencesURL != NULL) {
+               CFRelease(expectedPreferencesURL);
+       }
+       if (expectedNetworkInterfaceURL != NULL) {
+               CFRelease(expectedNetworkInterfaceURL);
+       }
+       if (prefsConfigString != NULL) {
+               CFRelease(prefsConfigString);
+       }
+       if (networkInterfaceConfigString != NULL) {
+               CFRelease(networkInterfaceConfigString);
+       }
+       if (prefsExpectedString != NULL) {
+               CFRelease(prefsExpectedString);
+       }
+       if (networkInterfaceExpectedString != NULL) {
+               CFRelease(networkInterfaceExpectedString);
+       }
+       if (configPref != NULL) {
+               CFRelease(configPref);
+       }
+       if (expectedConfigPref != NULL) {
+               CFRelease(expectedConfigPref);
+       }
+       if (configNetworkInterfacePref != NULL) {
+               CFRelease(configNetworkInterfacePref);
+       }
+       if (expectedNetworkInterfacePref != NULL) {
+               CFRelease(expectedNetworkInterfacePref);
+       }
+       return isIdentical;
+}
+
+CFArrayRef
+_SCNetworkConfigurationCopyMigrationRemovePaths        (CFArrayRef     targetPaths,
+                                                 CFURLRef      targetDir)
+{
+       CFURLRef affectedURL;
+       char filePath[PATH_MAX];
+       CFURLRef targetFile;
+       CFMutableArrayRef toBeRemoved = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       
+       for (CFIndex idx = 0; idx < CFArrayGetCount(targetPaths); idx++) {
+               affectedURL = CFArrayGetValueAtIndex(targetPaths, idx);
+               
+               if (CFURLGetFileSystemRepresentation(affectedURL, TRUE, (UInt8*)filePath, sizeof(filePath)) == FALSE) {
+                       SCLog(_sc_debug, LOG_NOTICE, CFSTR("filesToBeRemoved: Could not get file system representation"));
+                       continue;
+               }
+               targetFile = CFURLCreateFromFileSystemRepresentationRelativeToBase(NULL, (const UInt8*)filePath,
+               strnlen(filePath, sizeof(filePath)), FALSE, targetDir);
+               
+               if (CFURLResourceIsReachable(targetFile, NULL) == FALSE) {
+                       CFArrayAppendValue(toBeRemoved, affectedURL);
+               }
+               CFRelease(targetFile);
+       }
+       // If number of files to be removed is 0, return NULL
+       if (CFArrayGetCount(toBeRemoved) == 0) {
+               CFRelease(toBeRemoved);
+               toBeRemoved = NULL;
+       }
+       return toBeRemoved;
+}