Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ANPopupDialog.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ANPopupDialog.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ANPopupDialog.h	(working copy)
@@ -0,0 +1,29 @@
+//
+//  ANPopupDialog.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/7/18.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "ImportFile-Swift.h"
+
+@interface ANPopupDialog : NSObject
+
++ (PopupDialog *_Nullable)singleButtonPopupDialogWithTitle:(NSString * _Nullable)title message:(NSString * _Nullable)message;
++ (PopupDialog *_Nullable)singleButtonPopupDialogWithTitle:(NSString * _Nullable)title
+                                                   message:(NSString * _Nullable)message
+                                                    action:(void (^ _Nullable)(void))action;
++ (PopupDialog *_Nullable)doubleButtonsPopupDialogWithTitle:(NSString * _Nullable)title
+                                           message:(NSString * _Nullable)message
+                                     confirmAction:(void (^ _Nullable)(void))confirmAction
+                                      cancelAction:(void (^ _Nullable)(void))cancelAction;
++ (PopupDialog *_Nullable)doubleButtonsPopupDialogWithTitle:(NSString * _Nullable)title
+                                                    message:(NSString * _Nullable)message
+                                               confirmTitle:(NSString * _Nullable)confirmTitle
+                                                cancelTitle:(NSString * _Nullable)cancelTitle
+                                              confirmAction:(void (^ _Nullable)(void))confirmAction
+                                               cancelAction:(void (^ _Nullable)(void))cancelAction;
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ANPopupDialog.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ANPopupDialog.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ANPopupDialog.m	(working copy)
@@ -0,0 +1,98 @@
+//
+//  ANPopupDialog.m
+//  MacTunnel
+//
+//  Created by wangxy on 2017/7/18.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#import "Global.h"
+#import "ANPopupDialog.h"
+
+@implementation ANPopupDialog
+
++ (PopupDialog *)singleButtonPopupDialogWithTitle:(NSString *)title message:(NSString *)message {
+    return [self singleButtonPopupDialogWithTitle:title message:message action:nil];
+}
+
++ (PopupDialog *_Nullable)singleButtonPopupDialogWithTitle:(NSString * _Nullable)title
+                                                   message:(NSString * _Nullable)message
+                                                    action:(void (^ _Nullable)(void))action{
+    PopupDialog *popup = [[PopupDialog alloc] initWithTitle:title
+                                                    message:message
+                                                      image:nil
+                                            buttonAlignment:UILayoutConstraintAxisHorizontal
+                                            transitionStyle:PopupDialogTransitionStyleZoomIn
+                                           gestureDismissal:NO
+                                                 completion:nil];
+    
+    PopupDialogDefaultView *popupView = (PopupDialogDefaultView *)popup.viewController.view;
+    popupView.messageColor = UIColorFromRGBA(0, 1.0);
+    popupView.messageFont = [UIFont boldSystemFontOfSize:18];
+    popupView.messageTextAlignment = NSTextAlignmentCenter;
+    
+    DefaultButton *confirmButton = [[DefaultButton alloc] initWithTitle:NSLocalizedString(@"OK", nil)
+                                                                 height:50
+                                                           dismissOnTap:YES
+                                                                 action:action];
+    
+    confirmButton.titleFont = [UIFont systemFontOfSize:17];
+    confirmButton.titleColor = UIColorFromRGBA(0x007aff, 1.0);
+    
+    [popup addButton:confirmButton];
+    
+    return popup;
+}
+
++ (PopupDialog *_Nullable)doubleButtonsPopupDialogWithTitle:(NSString *)title
+                                                    message:(NSString *)message
+                                              confirmAction:(void (^)(void))confirmAction
+                                               cancelAction:(void (^)(void))cancelAction {
+    return [self doubleButtonsPopupDialogWithTitle:title
+                                           message:message
+                                      confirmTitle:NSLocalizedString(@"OK", nil)
+                                       cancelTitle:NSLocalizedString(@"Cancel", nil)
+                                     confirmAction:confirmAction
+                                      cancelAction:cancelAction];
+}
+
++ (PopupDialog *_Nullable)doubleButtonsPopupDialogWithTitle:(NSString * _Nullable)title
+                                                    message:(NSString * _Nullable)message
+                                               confirmTitle:(NSString * _Nullable)confirmTitle
+                                                cancelTitle:(NSString * _Nullable)cancelTitle
+                                              confirmAction:(void (^ _Nullable)(void))confirmAction
+                                               cancelAction:(void (^ _Nullable)(void))cancelAction{
+    PopupDialog *popup = [[PopupDialog alloc] initWithTitle:title
+                                                    message:message
+                                                      image:nil
+                                            buttonAlignment:UILayoutConstraintAxisHorizontal
+                                            transitionStyle:PopupDialogTransitionStyleZoomIn
+                                           gestureDismissal:NO
+                                                 completion:nil];
+    
+    PopupDialogDefaultView *popupView = (PopupDialogDefaultView *)popup.viewController.view;
+    popupView.messageColor = UIColorFromRGBA(0, 1.0);
+    popupView.messageFont = [UIFont boldSystemFontOfSize:18];
+    popupView.messageTextAlignment = NSTextAlignmentCenter;
+    
+    DefaultButton *confirmButton = [[DefaultButton alloc] initWithTitle:confirmTitle
+                                                                 height:50
+                                                           dismissOnTap:YES
+                                                                 action:confirmAction];
+    
+    DefaultButton *cancelButton = [[DefaultButton alloc] initWithTitle:cancelTitle
+                                                                height:50
+                                                          dismissOnTap:YES
+                                                                action:cancelAction];
+    
+    confirmButton.titleFont = [UIFont systemFontOfSize:17];
+    confirmButton.titleColor = UIColorFromRGBA(0x007aff, 1.0);
+    cancelButton.titleFont = [UIFont systemFontOfSize:17];
+    cancelButton.titleColor = UIColorFromRGBA(0x666666, 1.0);
+    
+    [popup addButtons:@[cancelButton, confirmButton]];
+    
+    return popup;
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/Base.lproj/MainInterface.storyboard
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/Base.lproj/MainInterface.storyboard	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/Base.lproj/MainInterface.storyboard	(working copy)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Share View Controller-->
+        <scene sceneID="ceB-am-kn3">
+            <objects>
+                <viewController id="j1y-V4-xli" customClass="ShareViewController" customModuleProvider="" sceneMemberID="viewController">
+                    <view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                        <viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+    </scenes>
+</document>
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.h	(working copy)
@@ -0,0 +1,13 @@
+//
+//  CustomShareViewController.h
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@interface CustomShareViewController : UIViewController
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.h.MotionProEnterprise
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.h.MotionProEnterprise	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.h.MotionProEnterprise	(working copy)
@@ -0,0 +1,15 @@
+//
+//  CustomShareViewController.h
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+NSString * const kAppGroupName = @"group.net.arraynetworks.groupenterprise";
+
+@interface CustomShareViewController : UIViewController
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m	(working copy)
@@ -0,0 +1,108 @@
+//
+//  CustomShareViewController.m
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+
+#import "CustomShareViewController.h"
+#import "ANPopupDialog.h"
+
+#if TARGET_OS_IPHONE
+NSString * const kAppGroupNameShare = @"group.net.arraynetworks.MotionProPlus";
+#elif TARGET_OS_MAC
+NSString * const kAppGroupNameShare = @"5VZLZ3YQ9P.net.arraynetworks.MacTunnel";
+#endif
+
+@interface CustomShareViewController ()
+
+@property (nonatomic, copy) NSData *certData;
+@property (nonatomic, copy) NSString *certName;
+
+@end
+
+@implementation CustomShareViewController
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    // Get cert message
+    __block BOOL hasGetUrl = NO;
+    [self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        [obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider *  _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
+            
+            if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"])
+            {
+                [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding>  _Nullable item, NSError * _Null_unspecified error) {
+                    
+                    if ([(NSObject *)item isKindOfClass:[NSURL class]])
+                    {
+                        dispatch_async(dispatch_get_main_queue(), ^{
+                            NSString *dialogMessage;
+                            self->_certName = [(NSURL *)item lastPathComponent];
+                            if ([self->_certName containsString:@".pfx"] || [self->_certName containsString:@".p12"]) {
+                                self->_certData = [NSData dataWithContentsOfURL:(NSURL*)item];
+                                dialogMessage = NSLocalizedString(@"Are you sure to import this certificate file?", nil);
+                            } else {
+                                dialogMessage = NSLocalizedString(@"Fail to import this file.", nil);
+                            }
+                            
+                            __weak typeof(self) weakSelf = self;
+                            PopupDialog *popup = [ANPopupDialog doubleButtonsPopupDialogWithTitle:nil
+                                                                                          message:dialogMessage
+                                                                                    confirmAction:^{
+                                                                                        [weakSelf postBtnClickHandler];
+                                                                                    }
+                                                                                     cancelAction:^{
+                                                                                         [weakSelf cancelBtnClickHandler];
+                                                                                     }];
+                            [self presentViewController:popup animated:YES completion:nil];
+                        });
+                    }
+                    
+                }];
+                
+                hasGetUrl = YES;
+                *stop = YES;
+            }
+            
+            *stop = hasGetUrl;
+            
+        }];
+        
+    }];
+}
+
+- (void)cancelBtnClickHandler
+{
+    [self.extensionContext cancelRequestWithError:[NSError errorWithDomain:@"CustomShareError" code:NSUserCancelledError userInfo:nil]];
+}
+
+- (void)postBtnClickHandler
+{
+    if (_certData) {
+        NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupNameShare];
+        NSString *certListCurrent = [userDefaults valueForKey:@"cert_list"];
+        NSLog(@"MotionProPlus import cert file name[%@], current import cert list[%@]", _certName, certListCurrent);
+        if (![certListCurrent containsString:_certName]) {
+            NSLog(@"The cert file name is new, need update current cert list.");
+            if ([certListCurrent length] > 0) {
+                certListCurrent = [certListCurrent stringByAppendingFormat:@",%@", _certName];
+            } else {
+                certListCurrent = _certName;
+            }
+        }
+        
+        NSLog(@"MotionProPlus new cert list[%@]", certListCurrent);
+        [userDefaults setValue:certListCurrent forKey:@"cert_list"];
+        
+        [userDefaults setValue:_certData forKey:_certName];
+    }
+    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.InfosecEnterprise
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.InfosecEnterprise	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.InfosecEnterprise	(working copy)
@@ -0,0 +1,108 @@
+//
+//  CustomShareViewController.m
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+
+#import "CustomShareViewController.h"
+#import "ANPopupDialog.h"
+
+#if TARGET_OS_IPHONE
+NSString * const kAppGroupNameShare = @"group.net.infosec.groupenterprise";
+#elif TARGET_OS_MAC
+NSString * const kAppGroupNameShare = @"5VZLZ3YQ9P.net.arraynetworks.MacTunnel";
+#endif
+
+@interface CustomShareViewController ()
+
+@property (nonatomic, copy) NSData *certData;
+@property (nonatomic, copy) NSString *certName;
+
+@end
+
+@implementation CustomShareViewController
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    // Get cert message
+    __block BOOL hasGetUrl = NO;
+    [self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        [obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider *  _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
+            
+            if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"])
+            {
+                [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding>  _Nullable item, NSError * _Null_unspecified error) {
+                    
+                    if ([(NSObject *)item isKindOfClass:[NSURL class]])
+                    {
+                        dispatch_async(dispatch_get_main_queue(), ^{
+                            NSString *dialogMessage;
+                            self->_certName = [(NSURL *)item lastPathComponent];
+                            if ([self->_certName containsString:@".pfx"] || [self->_certName containsString:@".p12"]) {
+                                self->_certData = [NSData dataWithContentsOfURL:(NSURL*)item];
+                                dialogMessage = NSLocalizedString(@"Are you sure to import this certificate file?", nil);
+                            } else {
+                                dialogMessage = NSLocalizedString(@"Fail to import this file.", nil);
+                            }
+                            
+                            __weak typeof(self) weakSelf = self;
+                            PopupDialog *popup = [ANPopupDialog doubleButtonsPopupDialogWithTitle:nil
+                                                                                          message:dialogMessage
+                                                                                    confirmAction:^{
+                                                                                        [weakSelf postBtnClickHandler];
+                                                                                    }
+                                                                                     cancelAction:^{
+                                                                                         [weakSelf cancelBtnClickHandler];
+                                                                                     }];
+                            [self presentViewController:popup animated:YES completion:nil];
+                        });
+                    }
+                    
+                }];
+                
+                hasGetUrl = YES;
+                *stop = YES;
+            }
+            
+            *stop = hasGetUrl;
+            
+        }];
+        
+    }];
+}
+
+- (void)cancelBtnClickHandler
+{
+    [self.extensionContext cancelRequestWithError:[NSError errorWithDomain:@"CustomShareError" code:NSUserCancelledError userInfo:nil]];
+}
+
+- (void)postBtnClickHandler
+{
+    if (_certData) {
+        NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupNameShare];
+        NSString *certListCurrent = [userDefaults valueForKey:@"cert_list"];
+        NSLog(@"MotionProPlus import cert file name[%@], current import cert list[%@]", _certName, certListCurrent);
+        if (![certListCurrent containsString:_certName]) {
+            NSLog(@"The cert file name is new, need update current cert list.");
+            if ([certListCurrent length] > 0) {
+                certListCurrent = [certListCurrent stringByAppendingFormat:@",%@", _certName];
+            } else {
+                certListCurrent = _certName;
+            }
+        }
+        
+        NSLog(@"MotionProPlus new cert list[%@]", certListCurrent);
+        [userDefaults setValue:certListCurrent forKey:@"cert_list"];
+        
+        [userDefaults setValue:_certData forKey:_certName];
+    }
+    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.InfosecStore
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.InfosecStore	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.InfosecStore	(working copy)
@@ -0,0 +1,108 @@
+//
+//  CustomShareViewController.m
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+
+#import "CustomShareViewController.h"
+#import "ANPopupDialog.h"
+
+#if TARGET_OS_IPHONE
+NSString * const kAppGroupNameShare = @"group.net.infosec.MotionPro";
+#elif TARGET_OS_MAC
+NSString * const kAppGroupNameShare = @"5VZLZ3YQ9P.net.arraynetworks.MacTunnel";
+#endif
+
+@interface CustomShareViewController ()
+
+@property (nonatomic, copy) NSData *certData;
+@property (nonatomic, copy) NSString *certName;
+
+@end
+
+@implementation CustomShareViewController
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    // Get cert message
+    __block BOOL hasGetUrl = NO;
+    [self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        [obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider *  _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
+            
+            if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"])
+            {
+                [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding>  _Nullable item, NSError * _Null_unspecified error) {
+                    
+                    if ([(NSObject *)item isKindOfClass:[NSURL class]])
+                    {
+                        dispatch_async(dispatch_get_main_queue(), ^{
+                            NSString *dialogMessage;
+                            self->_certName = [(NSURL *)item lastPathComponent];
+                            if ([self->_certName containsString:@".pfx"] || [self->_certName containsString:@".p12"]) {
+                                self->_certData = [NSData dataWithContentsOfURL:(NSURL*)item];
+                                dialogMessage = NSLocalizedString(@"Are you sure to import this certificate file?", nil);
+                            } else {
+                                dialogMessage = NSLocalizedString(@"Fail to import this file.", nil);
+                            }
+                            
+                            __weak typeof(self) weakSelf = self;
+                            PopupDialog *popup = [ANPopupDialog doubleButtonsPopupDialogWithTitle:nil
+                                                                                          message:dialogMessage
+                                                                                    confirmAction:^{
+                                                                                        [weakSelf postBtnClickHandler];
+                                                                                    }
+                                                                                     cancelAction:^{
+                                                                                         [weakSelf cancelBtnClickHandler];
+                                                                                     }];
+                            [self presentViewController:popup animated:YES completion:nil];
+                        });
+                    }
+                    
+                }];
+                
+                hasGetUrl = YES;
+                *stop = YES;
+            }
+            
+            *stop = hasGetUrl;
+            
+        }];
+        
+    }];
+}
+
+- (void)cancelBtnClickHandler
+{
+    [self.extensionContext cancelRequestWithError:[NSError errorWithDomain:@"CustomShareError" code:NSUserCancelledError userInfo:nil]];
+}
+
+- (void)postBtnClickHandler
+{
+    if (_certData) {
+        NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupNameShare];
+        NSString *certListCurrent = [userDefaults valueForKey:@"cert_list"];
+        NSLog(@"MotionProPlus import cert file name[%@], current import cert list[%@]", _certName, certListCurrent);
+        if (![certListCurrent containsString:_certName]) {
+            NSLog(@"The cert file name is new, need update current cert list.");
+            if ([certListCurrent length] > 0) {
+                certListCurrent = [certListCurrent stringByAppendingFormat:@",%@", _certName];
+            } else {
+                certListCurrent = _certName;
+            }
+        }
+        
+        NSLog(@"MotionProPlus new cert list[%@]", certListCurrent);
+        [userDefaults setValue:certListCurrent forKey:@"cert_list"];
+        
+        [userDefaults setValue:_certData forKey:_certName];
+    }
+    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.MotionPro
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.MotionPro	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.MotionPro	(working copy)
@@ -0,0 +1,108 @@
+//
+//  CustomShareViewController.m
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+
+#import "CustomShareViewController.h"
+#import "ANPopupDialog.h"
+
+#if TARGET_OS_IPHONE
+NSString * const kAppGroupNameShare = @"group.net.arraynetworks.MotionPro";
+#elif TARGET_OS_MAC
+NSString * const kAppGroupNameShare = @"5VZLZ3YQ9P.net.arraynetworks.MacTunnel";
+#endif
+
+@interface CustomShareViewController ()
+
+@property (nonatomic, copy) NSData *certData;
+@property (nonatomic, copy) NSString *certName;
+
+@end
+
+@implementation CustomShareViewController
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    // Get cert message
+    __block BOOL hasGetUrl = NO;
+    [self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        [obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider *  _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
+            
+            if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"])
+            {
+                [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding>  _Nullable item, NSError * _Null_unspecified error) {
+                    
+                    if ([(NSObject *)item isKindOfClass:[NSURL class]])
+                    {
+                        dispatch_async(dispatch_get_main_queue(), ^{
+                            NSString *dialogMessage;
+                            self->_certName = [(NSURL *)item lastPathComponent];
+                            if ([self->_certName containsString:@".pfx"] || [self->_certName containsString:@".p12"]) {
+                                self->_certData = [NSData dataWithContentsOfURL:(NSURL*)item];
+                                dialogMessage = NSLocalizedString(@"Are you sure to import this certificate file?", nil);
+                            } else {
+                                dialogMessage = NSLocalizedString(@"Fail to import this file.", nil);
+                            }
+                            
+                            __weak typeof(self) weakSelf = self;
+                            PopupDialog *popup = [ANPopupDialog doubleButtonsPopupDialogWithTitle:nil
+                                                                                          message:dialogMessage
+                                                                                    confirmAction:^{
+                                                                                        [weakSelf postBtnClickHandler];
+                                                                                    }
+                                                                                     cancelAction:^{
+                                                                                         [weakSelf cancelBtnClickHandler];
+                                                                                     }];
+                            [self presentViewController:popup animated:YES completion:nil];
+                        });
+                    }
+                    
+                }];
+                
+                hasGetUrl = YES;
+                *stop = YES;
+            }
+            
+            *stop = hasGetUrl;
+            
+        }];
+        
+    }];
+}
+
+- (void)cancelBtnClickHandler
+{
+    [self.extensionContext cancelRequestWithError:[NSError errorWithDomain:@"CustomShareError" code:NSUserCancelledError userInfo:nil]];
+}
+
+- (void)postBtnClickHandler
+{
+    if (_certData) {
+        NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupNameShare];
+        NSString *certListCurrent = [userDefaults valueForKey:@"cert_list"];
+        NSLog(@"MotionProPlus import cert file name[%@], current import cert list[%@]", _certName, certListCurrent);
+        if (![certListCurrent containsString:_certName]) {
+            NSLog(@"The cert file name is new, need update current cert list.");
+            if ([certListCurrent length] > 0) {
+                certListCurrent = [certListCurrent stringByAppendingFormat:@",%@", _certName];
+            } else {
+                certListCurrent = _certName;
+            }
+        }
+        
+        NSLog(@"MotionProPlus new cert list[%@]", certListCurrent);
+        [userDefaults setValue:certListCurrent forKey:@"cert_list"];
+        
+        [userDefaults setValue:_certData forKey:_certName];
+    }
+    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.MotionProEnterprise
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.MotionProEnterprise	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/CustomShareViewController.m.MotionProEnterprise	(working copy)
@@ -0,0 +1,108 @@
+//
+//  CustomShareViewController.m
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+
+#import "CustomShareViewController.h"
+#import "ANPopupDialog.h"
+
+#if TARGET_OS_IPHONE
+NSString * const kAppGroupNameShare = @"group.net.arraynetworks.groupenterprise";
+#elif TARGET_OS_MAC
+NSString * const kAppGroupNameShare = @"5VZLZ3YQ9P.net.arraynetworks.MacTunnel";
+#endif
+
+@interface CustomShareViewController ()
+
+@property (nonatomic, copy) NSData *certData;
+@property (nonatomic, copy) NSString *certName;
+
+@end
+
+@implementation CustomShareViewController
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    
+    // Get cert message
+    __block BOOL hasGetUrl = NO;
+    [self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        [obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider *  _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
+            
+            if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"])
+            {
+                [itemProvider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding>  _Nullable item, NSError * _Null_unspecified error) {
+                    
+                    if ([(NSObject *)item isKindOfClass:[NSURL class]])
+                    {
+                        dispatch_async(dispatch_get_main_queue(), ^{
+                            NSString *dialogMessage;
+                            self->_certName = [(NSURL *)item lastPathComponent];
+                            if ([self->_certName containsString:@".pfx"] || [self->_certName containsString:@".p12"]) {
+                                self->_certData = [NSData dataWithContentsOfURL:(NSURL*)item];
+                                dialogMessage = NSLocalizedString(@"Are you sure to import this certificate file?", nil);
+                            } else {
+                                dialogMessage = NSLocalizedString(@"Fail to import this file.", nil);
+                            }
+                            
+                            __weak typeof(self) weakSelf = self;
+                            PopupDialog *popup = [ANPopupDialog doubleButtonsPopupDialogWithTitle:nil
+                                                                                          message:dialogMessage
+                                                                                    confirmAction:^{
+                                                                                        [weakSelf postBtnClickHandler];
+                                                                                    }
+                                                                                     cancelAction:^{
+                                                                                         [weakSelf cancelBtnClickHandler];
+                                                                                     }];
+                            [self presentViewController:popup animated:YES completion:nil];
+                        });
+                    }
+                    
+                }];
+                
+                hasGetUrl = YES;
+                *stop = YES;
+            }
+            
+            *stop = hasGetUrl;
+            
+        }];
+        
+    }];
+}
+
+- (void)cancelBtnClickHandler
+{
+    [self.extensionContext cancelRequestWithError:[NSError errorWithDomain:@"CustomShareError" code:NSUserCancelledError userInfo:nil]];
+}
+
+- (void)postBtnClickHandler
+{
+    if (_certData) {
+        NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroupNameShare];
+        NSString *certListCurrent = [userDefaults valueForKey:@"cert_list"];
+        NSLog(@"MotionProPlus import cert file name[%@], current import cert list[%@]", _certName, certListCurrent);
+        if (![certListCurrent containsString:_certName]) {
+            NSLog(@"The cert file name is new, need update current cert list.");
+            if ([certListCurrent length] > 0) {
+                certListCurrent = [certListCurrent stringByAppendingFormat:@",%@", _certName];
+            } else {
+                certListCurrent = _certName;
+            }
+        }
+        
+        NSLog(@"MotionProPlus new cert list[%@]", certListCurrent);
+        [userDefaults setValue:certListCurrent forKey:@"cert_list"];
+        
+        [userDefaults setValue:_certData forKey:_certName];
+    }
+    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
+}
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile-Bridging-Header.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile-Bridging-Header.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile-Bridging-Header.h	(working copy)
@@ -0,0 +1,14 @@
+//
+//  MotionProPlus-Bridging-Header.h
+//  MacTunnel
+//
+//  Created by wangxy on 2017/7/18.
+//  Copyright © 2017年 wangxy. All rights reserved.
+//
+
+#ifndef MotionProPlus_Bridging_Header_h
+#define MotionProPlus_Bridging_Header_h
+
+#import "FXBlurView.h"
+
+#endif /* MotionProPlus_Bridging_Header_h */
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements	(working copy)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.application-groups</key>
+	<array>
+		<string>group.net.arraynetworks.MotionProPlus</string>
+	</array>
+</dict>
+</plist>
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.InfosecEnterprise
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.InfosecEnterprise	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.InfosecEnterprise	(working copy)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.application-groups</key>
+	<array>
+		<string>group.net.infosec.groupenterprise</string>
+	</array>
+</dict>
+</plist>
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.InfosecStore
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.InfosecStore	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.InfosecStore	(working copy)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.application-groups</key>
+	<array>
+		<string>group.net.infosec.MotionPro</string>
+	</array>
+</dict>
+</plist>
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.MotionPro
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.MotionPro	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.MotionPro	(working copy)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.application-groups</key>
+	<array>
+		<string>group.net.arraynetworks.MotionPro</string>
+	</array>
+</dict>
+</plist>
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.MotionProEnterprise
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.MotionProEnterprise	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ImportFile.entitlements.MotionProEnterprise	(working copy)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>com.apple.security.application-groups</key>
+	<array>
+		<string>group.net.arraynetworks.groupenterprise</string>
+	</array>
+</dict>
+</plist>
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/Info.plist
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/Info.plist	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/Info.plist	(working copy)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>NSExtension</key>
+	<dict>
+		<key>NSExtensionAttributes</key>
+		<dict>
+			<key>NSExtensionActivationRule</key>
+			<dict>
+				<key>NSExtensionActivationSupportsAttachmentsWithMaxCount</key>
+				<integer>100</integer>
+			</dict>
+		</dict>
+		<key>NSExtensionPointIdentifier</key>
+		<string>com.apple.share-services</string>
+		<key>NSExtensionPrincipalClass</key>
+		<string>CustomShareViewController</string>
+	</dict>
+</dict>
+</plist>
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/FXBlurView.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/FXBlurView.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/FXBlurView.h	(working copy)
@@ -0,0 +1,81 @@
+//
+//  FXBlurView.h
+//
+//  Version 1.6.4
+//
+//  Created by Nick Lockwood on 25/08/2013.
+//  Copyright (c) 2013 Charcoal Design
+//
+//  Distributed under the permissive zlib License
+//  Get the latest version from here:
+//
+//  https://github.com/nicklockwood/FXBlurView
+//
+//  This software is provided 'as-is', without any express or implied
+//  warranty.  In no event will the authors be held liable for any damages
+//  arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,
+//  including commercial applications, and to alter it and redistribute it
+//  freely, subject to the following restrictions:
+//
+//  1. The origin of this software must not be misrepresented; you must not
+//  claim that you wrote the original software. If you use this software
+//  in a product, an acknowledgment in the product documentation would be
+//  appreciated but is not required.
+//
+//  2. Altered source versions must be plainly marked as such, and must not be
+//  misrepresented as being the original software.
+//
+//  3. This notice may not be removed or altered from any source distribution.
+//
+
+
+#import <UIKit/UIKit.h>
+#import <QuartzCore/QuartzCore.h>
+#import <Accelerate/Accelerate.h>
+
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis"
+
+
+#import <Availability.h>
+#undef weak_ref
+#if __has_feature(objc_arc) && __has_feature(objc_arc_weak)
+#define weak_ref weak
+#else
+#define weak_ref unsafe_unretained
+#endif
+
+
+@interface UIImage (FXBlurView)
+
+- (UIImage *)blurredImageWithRadius:(CGFloat)radius iterations:(NSUInteger)iterations tintColor:(UIColor *)tintColor;
+
+@end
+
+
+@interface FXBlurView : UIView
+
++ (void)setBlurEnabled:(BOOL)blurEnabled;
++ (void)setUpdatesEnabled;
++ (void)setUpdatesDisabled;
+
+@property (nonatomic, getter = isBlurEnabled) BOOL blurEnabled;
+@property (nonatomic, getter = isDynamic) BOOL dynamic;
+@property (nonatomic, assign) NSUInteger iterations;
+@property (nonatomic, assign) NSTimeInterval updateInterval;
+@property (nonatomic, assign) CGFloat blurRadius;
+@property (nonatomic, strong) UIColor *tintColor;
+@property (nonatomic, weak_ref) IBOutlet UIView *underlyingView;
+
+- (void)updateAsynchronously:(BOOL)async completion:(void (^)(void))completion;
+
+- (void)clearImage;
+
+@end
+
+
+#pragma GCC diagnostic pop
+
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/FXBlurView.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/FXBlurView.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/FXBlurView.m	(working copy)
@@ -0,0 +1,712 @@
+//
+//  FXBlurView.m
+//
+//  Version 1.6.4
+//
+//  Created by Nick Lockwood on 25/08/2013.
+//  Copyright (c) 2013 Charcoal Design
+//
+//  Distributed under the permissive zlib License
+//  Get the latest version from here:
+//
+//  https://github.com/nicklockwood/FXBlurView
+//
+//  This software is provided 'as-is', without any express or implied
+//  warranty.  In no event will the authors be held liable for any damages
+//  arising from the use of this software.
+//
+//  Permission is granted to anyone to use this software for any purpose,
+//  including commercial applications, and to alter it and redistribute it
+//  freely, subject to the following restrictions:
+//
+//  1. The origin of this software must not be misrepresented; you must not
+//  claim that you wrote the original software. If you use this software
+//  in a product, an acknowledgment in the product documentation would be
+//  appreciated but is not required.
+//
+//  2. Altered source versions must be plainly marked as such, and must not be
+//  misrepresented as being the original software.
+//
+//  3. This notice may not be removed or altered from any source distribution.
+//
+
+
+#import "FXBlurView.h"
+#import <objc/runtime.h>
+
+
+#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis"
+#pragma GCC diagnostic ignored "-Wdirect-ivar-access"
+#pragma GCC diagnostic ignored "-Wgnu"
+
+
+#import <Availability.h>
+#if !__has_feature(objc_arc)
+#error This class requires automatic reference counting
+#endif
+
+
+@implementation UIImage (FXBlurView)
+
+- (UIImage *)blurredImageWithRadius:(CGFloat)radius iterations:(NSUInteger)iterations tintColor:(UIColor *)tintColor
+{
+    //image must be nonzero size
+    if (floorf(self.size.width) * floorf(self.size.height) <= 0.0f) return self;
+
+    //boxsize must be an odd integer
+    uint32_t boxSize = (uint32_t)(radius * self.scale);
+    if (boxSize % 2 == 0) boxSize ++;
+
+    //create image buffers
+    CGImageRef imageRef = self.CGImage;
+
+    //convert to ARGB if it isn't
+    if (CGImageGetBitsPerPixel(imageRef) != 32 ||
+        CGImageGetBitsPerComponent(imageRef) != 8 ||
+        !((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask)))
+    {
+        UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
+        [self drawAtPoint:CGPointZero];
+        imageRef = UIGraphicsGetImageFromCurrentImageContext().CGImage;
+        UIGraphicsEndImageContext();
+    }
+
+    vImage_Buffer buffer1, buffer2;
+    buffer1.width = buffer2.width = CGImageGetWidth(imageRef);
+    buffer1.height = buffer2.height = CGImageGetHeight(imageRef);
+    buffer1.rowBytes = buffer2.rowBytes = CGImageGetBytesPerRow(imageRef);
+    size_t bytes = buffer1.rowBytes * buffer1.height;
+    buffer1.data = malloc(bytes);
+    buffer2.data = malloc(bytes);
+
+    //create temp buffer
+    void *tempBuffer = malloc((size_t)vImageBoxConvolve_ARGB8888(&buffer1, &buffer2, NULL, 0, 0, boxSize, boxSize,
+                                                                 NULL, kvImageEdgeExtend + kvImageGetTempBufferSize));
+
+    //copy image data
+    CFDataRef dataSource = CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
+    memcpy(buffer1.data, CFDataGetBytePtr(dataSource), bytes);
+    CFRelease(dataSource);
+
+    for (NSUInteger i = 0; i < iterations; i++)
+    {
+        //perform blur
+        vImageBoxConvolve_ARGB8888(&buffer1, &buffer2, tempBuffer, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
+
+        //swap buffers
+        void *temp = buffer1.data;
+        buffer1.data = buffer2.data;
+        buffer2.data = temp;
+    }
+
+    //free buffers
+    free(buffer2.data);
+    free(tempBuffer);
+
+    //create image context from buffer
+    CGContextRef ctx = CGBitmapContextCreate(buffer1.data, buffer1.width, buffer1.height,
+                                             8, buffer1.rowBytes, CGImageGetColorSpace(imageRef),
+                                             CGImageGetBitmapInfo(imageRef));
+
+    //apply tint
+    if (tintColor && CGColorGetAlpha(tintColor.CGColor) > 0.0f)
+    {
+        CGContextSetFillColorWithColor(ctx, [tintColor colorWithAlphaComponent:0.25].CGColor);
+        CGContextSetBlendMode(ctx, kCGBlendModePlusLighter);
+        CGContextFillRect(ctx, CGRectMake(0, 0, buffer1.width, buffer1.height));
+    }
+
+    //create image from context
+    imageRef = CGBitmapContextCreateImage(ctx);
+    UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
+    CGImageRelease(imageRef);
+    CGContextRelease(ctx);
+    free(buffer1.data);
+    return image;
+}
+
+@end
+
+
+@interface FXBlurScheduler : NSObject
+
+@property (nonatomic, strong) NSMutableArray *views;
+@property (nonatomic, assign) NSUInteger viewIndex;
+@property (nonatomic, assign) NSUInteger updatesEnabled;
+@property (nonatomic, assign) BOOL blurEnabled;
+@property (nonatomic, assign) BOOL updating;
+
+@end
+
+
+@interface FXBlurLayer: CALayer
+
+@property (nonatomic, assign) CGFloat blurRadius;
+
+@end
+
+
+@implementation FXBlurLayer
+
+@dynamic blurRadius;
+
++ (BOOL)needsDisplayForKey:(NSString *)key
+{
+    if ([@[@"blurRadius", @"bounds", @"position"] containsObject:key])
+    {
+        return YES;
+    }
+    return [super needsDisplayForKey:key];
+}
+
+@end
+
+
+@interface FXBlurView ()
+
+@property (nonatomic, assign) BOOL iterationsSet;
+@property (nonatomic, assign) BOOL blurRadiusSet;
+@property (nonatomic, assign) BOOL dynamicSet;
+@property (nonatomic, assign) BOOL blurEnabledSet;
+@property (nonatomic, strong) NSDate *lastUpdate;
+@property (nonatomic, assign) BOOL needsDrawViewHierarchy;
+
+- (UIImage *)snapshotOfUnderlyingView;
+- (BOOL)shouldUpdate;
+
+@end
+
+
+@implementation FXBlurScheduler
+
++ (instancetype)sharedInstance
+{
+    static FXBlurScheduler *sharedInstance = nil;
+    if (!sharedInstance)
+    {
+        sharedInstance = [[FXBlurScheduler alloc] init];
+    }
+    return sharedInstance;
+}
+
+- (instancetype)init
+{
+    if ((self = [super init]))
+    {
+        _updatesEnabled = 1;
+        _blurEnabled = YES;
+        _views = [[NSMutableArray alloc] init];
+    }
+    return self;
+}
+
+- (void)setBlurEnabled:(BOOL)blurEnabled
+{
+    _blurEnabled = blurEnabled;
+    if (blurEnabled)
+    {
+        for (FXBlurView *view in self.views)
+        {
+            [view setNeedsDisplay];
+        }
+        [self updateAsynchronously];
+    }
+}
+
+- (void)setUpdatesEnabled
+{
+    _updatesEnabled ++;
+    [self updateAsynchronously];
+}
+
+- (void)setUpdatesDisabled
+{
+    _updatesEnabled --;
+}
+
+- (void)addView:(FXBlurView *)view
+{
+    if (![self.views containsObject:view])
+    {
+        [self.views addObject:view];
+        [self updateAsynchronously];
+    }
+}
+
+- (void)removeView:(FXBlurView *)view
+{
+    NSUInteger index = [self.views indexOfObject:view];
+    if (index != NSNotFound)
+    {
+        if (index <= self.viewIndex)
+        {
+            self.viewIndex --;
+        }
+        [self.views removeObjectAtIndex:index];
+    }
+}
+
+- (void)updateAsynchronously
+{
+    if (self.blurEnabled && !self.updating && self.updatesEnabled > 0 && [self.views count])
+    {
+        NSTimeInterval timeUntilNextUpdate = 1.0 / 60;
+
+        //loop through until we find a view that's ready to be drawn
+        self.viewIndex = self.viewIndex % [self.views count];
+        for (NSUInteger i = self.viewIndex; i < [self.views count]; i++)
+        {
+            FXBlurView *view = self.views[i];
+            if (view.dynamic && !view.hidden && view.window && [view shouldUpdate])
+            {
+                NSTimeInterval nextUpdate = [view.lastUpdate timeIntervalSinceNow] + view.updateInterval;
+                if (!view.lastUpdate || nextUpdate <= 0)
+                {
+                    self.updating = YES;
+                    [view updateAsynchronously:YES completion:^{
+
+                        //render next view
+                        self.updating = NO;
+                        self.viewIndex = i + 1;
+                        [self updateAsynchronously];
+                    }];
+                    return;
+                }
+                else
+                {
+                    timeUntilNextUpdate = MIN(timeUntilNextUpdate, nextUpdate);
+                }
+            }
+        }
+
+        //try again, delaying until the time when the next view needs an update.
+        self.viewIndex = 0;
+        [self performSelector:@selector(updateAsynchronously)
+                   withObject:nil
+                   afterDelay:timeUntilNextUpdate
+                      inModes:@[NSDefaultRunLoopMode, UITrackingRunLoopMode]];
+    }
+}
+
+@end
+
+
+@implementation FXBlurView
+
+@synthesize underlyingView = _underlyingView;
+
++ (void)setBlurEnabled:(BOOL)blurEnabled
+{
+    [FXBlurScheduler sharedInstance].blurEnabled = blurEnabled;
+}
+
++ (void)setUpdatesEnabled
+{
+    [[FXBlurScheduler sharedInstance] setUpdatesEnabled];
+}
+
++ (void)setUpdatesDisabled
+{
+    [[FXBlurScheduler sharedInstance] setUpdatesDisabled];
+}
+
++ (Class)layerClass
+{
+    return [FXBlurLayer class];
+}
+
+- (void)setUp
+{
+    if (!_iterationsSet) _iterations = 3;
+    if (!_blurRadiusSet) [self blurLayer].blurRadius = 40;
+    if (!_dynamicSet) _dynamic = YES;
+    if (!_blurEnabledSet) _blurEnabled = YES;
+    self.updateInterval = _updateInterval;
+    self.layer.magnificationFilter = @"linear"; // kCAFilterLinear
+
+    unsigned int numberOfMethods;
+    Method *methods = class_copyMethodList([UIView class], &numberOfMethods);
+    for (unsigned int i = 0; i < numberOfMethods; i++)
+    {
+        Method method = methods[i];
+        SEL selector = method_getName(method);
+        if (selector == @selector(tintColor))
+        {
+            _tintColor = ((id (*)(id,SEL))method_getImplementation(method))(self, selector);
+            break;
+        }
+    }
+    free(methods);
+
+}
+
+- (id)initWithFrame:(CGRect)frame
+{
+    if ((self = [super initWithFrame:frame]))
+    {
+        [self setUp];
+        self.clipsToBounds = YES;
+    }
+    return self;
+}
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    if ((self = [super initWithCoder:aDecoder]))
+    {
+        [self setUp];
+    }
+    return self;
+}
+
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+
+- (BOOL)viewOrSubviewNeedsDrawViewHierarchy:(UIView *)view
+{
+    if ([view isKindOfClass:NSClassFromString(@"SKView")] ||
+        [view.layer isKindOfClass:NSClassFromString(@"CAEAGLLayer")] ||
+        [view.layer isKindOfClass:NSClassFromString(@"AVPlayerLayer")] ||
+        ABS(view.layer.transform.m34) > 0)
+    {
+        return YES;
+    }
+    for (UIView *subview in view.subviews)
+    {
+        if ([self viewOrSubviewNeedsDrawViewHierarchy:subview])
+        {
+            return YES;
+        }
+    }
+    return  NO;
+}
+
+- (void)willMoveToSuperview:(UIView *)newSuperview
+{
+    [super willMoveToSuperview:newSuperview];
+    if (!_underlyingView)
+    {
+        _needsDrawViewHierarchy = [self viewOrSubviewNeedsDrawViewHierarchy:newSuperview];
+    }
+}
+
+- (void)setIterations:(NSUInteger)iterations
+{
+    _iterationsSet = YES;
+    _iterations = iterations;
+    [self setNeedsDisplay];
+}
+
+- (void)setBlurRadius:(CGFloat)blurRadius
+{
+    _blurRadiusSet = YES;
+    [self blurLayer].blurRadius = blurRadius;
+}
+
+- (CGFloat)blurRadius
+{
+    return [self blurLayer].blurRadius;
+}
+
+- (void)setBlurEnabled:(BOOL)blurEnabled
+{
+    _blurEnabledSet = YES;
+    if (_blurEnabled != blurEnabled)
+    {
+        _blurEnabled = blurEnabled;
+        [self schedule];
+        if (_blurEnabled)
+        {
+            [self setNeedsDisplay];
+        }
+    }
+}
+
+- (void)setDynamic:(BOOL)dynamic
+{
+    _dynamicSet = YES;
+    if (_dynamic != dynamic)
+    {
+        _dynamic = dynamic;
+        [self schedule];
+        if (!dynamic)
+        {
+            [self setNeedsDisplay];
+        }
+    }
+}
+
+- (UIView *)underlyingView
+{
+    return _underlyingView ?: self.superview;
+}
+
+- (void)setUnderlyingView:(UIView *)underlyingView
+{
+    _underlyingView = underlyingView;
+    _needsDrawViewHierarchy = [self viewOrSubviewNeedsDrawViewHierarchy:self.underlyingView];
+    [self setNeedsDisplay];
+}
+
+- (CALayer *)underlyingLayer
+{
+    return self.underlyingView.layer;
+}
+
+- (FXBlurLayer *)blurLayer
+{
+    return (FXBlurLayer *)self.layer;
+}
+
+- (FXBlurLayer *)blurPresentationLayer
+{
+    FXBlurLayer *blurLayer = [self blurLayer];
+    return (FXBlurLayer *)blurLayer.presentationLayer ?: blurLayer;
+}
+
+- (void)setUpdateInterval:(NSTimeInterval)updateInterval
+{
+    _updateInterval = updateInterval;
+    if (_updateInterval <= 0) _updateInterval = 1.0/60;
+}
+
+- (void)setTintColor:(UIColor *)tintColor
+{
+    _tintColor = tintColor;
+    [self setNeedsDisplay];
+}
+
+- (void)clearImage {
+    self.layer.contents = nil;
+    [self setNeedsDisplay];
+}
+
+- (void)didMoveToSuperview
+{
+    [super didMoveToSuperview];
+    [self.layer setNeedsDisplay];
+}
+
+- (void)didMoveToWindow
+{
+    [super didMoveToWindow];
+    [self schedule];
+}
+
+- (void)schedule
+{
+    if (self.window && self.dynamic && self.blurEnabled)
+    {
+        [[FXBlurScheduler sharedInstance] addView:self];
+    }
+    else
+    {
+        [[FXBlurScheduler sharedInstance] removeView:self];
+    }
+}
+
+- (void)setNeedsDisplay
+{
+    [super setNeedsDisplay];
+    [self.layer setNeedsDisplay];
+}
+
+- (BOOL)shouldUpdate
+{
+    __strong CALayer *underlyingLayer = [self underlyingLayer];
+
+    return
+    underlyingLayer && !underlyingLayer.hidden &&
+    self.blurEnabled && [FXBlurScheduler sharedInstance].blurEnabled &&
+    !CGRectIsEmpty([self.layer.presentationLayer ?: self.layer bounds]) && !CGRectIsEmpty(underlyingLayer.bounds);
+}
+
+- (void)displayLayer:(__unused CALayer *)layer
+{
+    [self updateAsynchronously:NO completion:NULL];
+}
+
+- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)key
+{
+    if ([key isEqualToString:@"blurRadius"])
+    {
+        //animations are enabled
+        CAAnimation *action = (CAAnimation *)[super actionForLayer:layer forKey:@"backgroundColor"];
+        if ((NSNull *)action != [NSNull null])
+        {
+            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:key];
+            animation.fromValue = [layer.presentationLayer valueForKey:key];
+
+            //CAMediatiming attributes
+            animation.beginTime = action.beginTime;
+            animation.duration = action.duration;
+            animation.speed = action.speed;
+            animation.timeOffset = action.timeOffset;
+            animation.repeatCount = action.repeatCount;
+            animation.repeatDuration = action.repeatDuration;
+            animation.autoreverses = action.autoreverses;
+            animation.fillMode = action.fillMode;
+
+            //CAAnimation attributes
+            animation.timingFunction = action.timingFunction;
+            animation.delegate = action.delegate;
+
+            return animation;
+        }
+    }
+    return [super actionForLayer:layer forKey:key];
+}
+
+- (UIImage *)snapshotOfUnderlyingView
+{
+    __strong FXBlurLayer *blurLayer = [self blurPresentationLayer];
+    __strong CALayer *underlyingLayer = [self underlyingLayer];
+    CGRect bounds = [blurLayer convertRect:blurLayer.bounds toLayer:underlyingLayer];
+
+    self.lastUpdate = [NSDate date];
+    CGFloat scale = 0.5;
+    if (self.iterations)
+    {
+        CGFloat blockSize = 12.0/self.iterations;
+        scale = blockSize/MAX(blockSize * 2, blurLayer.blurRadius);
+        scale = 1.0/floor(1.0/scale);
+    }
+    CGSize size = bounds.size;
+    if (self.contentMode == UIViewContentModeScaleToFill ||
+        self.contentMode == UIViewContentModeScaleAspectFill ||
+        self.contentMode == UIViewContentModeScaleAspectFit ||
+        self.contentMode == UIViewContentModeRedraw)
+    {
+        //prevents edge artefacts
+        size.width = floor(size.width * scale) / scale;
+        size.height = floor(size.height * scale) / scale;
+    }
+    else if ([[UIDevice currentDevice].systemVersion floatValue] < 7.0 && [UIScreen mainScreen].scale == 1.0)
+    {
+        //prevents pixelation on old devices
+        scale = 1.0;
+    }
+    UIGraphicsBeginImageContextWithOptions(size, NO, scale);
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    if (context)
+    {
+        CGContextTranslateCTM(context, -bounds.origin.x, -bounds.origin.y);
+
+        NSArray *hiddenViews = [self prepareUnderlyingViewForSnapshot];
+        if (self.needsDrawViewHierarchy)
+        {
+            __strong UIView *underlyingView = self.underlyingView;
+            [underlyingView drawViewHierarchyInRect:underlyingView.bounds afterScreenUpdates:YES];
+        }
+        else
+        {
+            [underlyingLayer renderInContext:context];
+        }
+        [self restoreSuperviewAfterSnapshot:hiddenViews];
+        UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
+        UIGraphicsEndImageContext();
+        return snapshot;
+    }
+    return nil;
+}
+
+- (NSArray *)hideEmptyLayers:(CALayer *)layer
+{
+    NSMutableArray *layers = [NSMutableArray array];
+    
+    // See https://github.com/nicklockwood/FXBlurView/issues/126
+    if (CGRectIsEmpty(layer.bounds) && !layer.hidden)
+    {
+        layer.hidden = YES;
+        [layers addObject:layer];
+    }
+    for (CALayer *sublayer in layer.sublayers)
+    {
+        [layers addObjectsFromArray:[self hideEmptyLayers:sublayer]];
+    }
+    return layers;
+}
+
+- (NSArray *)prepareUnderlyingViewForSnapshot
+{
+    __strong CALayer *blurlayer = [self blurLayer];
+    __strong CALayer *underlyingLayer = [self underlyingLayer];
+    while (blurlayer.superlayer && blurlayer.superlayer != underlyingLayer)
+    {
+        blurlayer = blurlayer.superlayer;
+    }
+    NSMutableArray *layers = [NSMutableArray array];
+    NSUInteger index = [underlyingLayer.sublayers indexOfObject:blurlayer];
+    if (index != NSNotFound)
+    {
+        for (NSUInteger i = index; i < [underlyingLayer.sublayers count]; i++)
+        {
+            CALayer *layer = underlyingLayer.sublayers[i];
+            if (!layer.hidden)
+            {
+                layer.hidden = YES;
+                [layers addObject:layer];
+            }
+        }
+    }
+
+    //also hide any sublayers with empty bounds to prevent a crash on iOS 8
+    [layers addObjectsFromArray:[self hideEmptyLayers:underlyingLayer]];
+
+    return layers;
+}
+
+- (void)restoreSuperviewAfterSnapshot:(NSArray *)hiddenLayers
+{
+    for (CALayer *layer in hiddenLayers)
+    {
+        layer.hidden = NO;
+    }
+}
+
+- (UIImage *)blurredSnapshot:(UIImage *)snapshot radius:(CGFloat)blurRadius
+{
+    return [snapshot blurredImageWithRadius:blurRadius
+                                 iterations:self.iterations
+                                  tintColor:self.tintColor];
+}
+
+- (void)setLayerContents:(UIImage *)image
+{
+    self.layer.contents = (id)image.CGImage;
+    self.layer.contentsScale = image.scale;
+}
+
+- (void)updateAsynchronously:(BOOL)async completion:(void (^)(void))completion
+{
+    if ([self shouldUpdate])
+    {
+        UIImage *snapshot = [self snapshotOfUnderlyingView];
+        if (async)
+        {
+            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+
+                UIImage *blurredImage = [self blurredSnapshot:snapshot radius:self.blurRadius];
+                dispatch_sync(dispatch_get_main_queue(), ^{
+
+                    [self setLayerContents:blurredImage];
+                    if (completion) completion();
+                });
+            });
+        }
+        else
+        {
+            [self setLayerContents:[self blurredSnapshot:snapshot radius:[self blurPresentationLayer].blurRadius]];
+            if (completion) completion();
+        }
+    }
+    else if (completion)
+    {
+        completion();
+    }
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/InteractiveTransition.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/InteractiveTransition.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/InteractiveTransition.swift	(working copy)
@@ -0,0 +1,86 @@
+//
+//  PopupDialogInteractiveTransition.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import UIKit
+
+// Handles interactive transition triggered via pan gesture recognizer on dialog
+final internal class InteractiveTransition: UIPercentDrivenInteractiveTransition {
+
+    // If the interactive transition was started
+    var hasStarted = false
+
+    // If the interactive transition
+    var shouldFinish = false
+
+    // The view controller containing the views
+    // with attached gesture recognizers
+    weak var viewController: UIViewController? = nil
+
+    @objc func handlePan(_ sender: UIPanGestureRecognizer) {
+
+        guard let vc = viewController else { return }
+
+        guard let progress = calculateProgress(sender: sender) else { return }
+
+        switch sender.state {
+        case .began:
+            hasStarted = true
+            vc.dismiss(animated: true, completion: nil)
+        case .changed:
+            shouldFinish = progress > 0.3
+            update(progress)
+        case .cancelled:
+            hasStarted = false
+            cancel()
+        case .ended:
+            hasStarted = false
+            completionSpeed = 0.55
+            shouldFinish ? finish() : cancel()
+        default:
+            break
+        }
+    }
+}
+
+internal extension InteractiveTransition {
+
+    /*!
+     Translates the pan gesture recognizer position to the progress percentage
+     - parameter sender: A UIPanGestureRecognizer
+     - returns: Progress
+     */
+    func calculateProgress(sender: UIPanGestureRecognizer) -> CGFloat? {
+        guard let vc = viewController else { return nil }
+
+        // http://www.thorntech.com/2016/02/ios-tutorial-close-modal-dragging/
+        let translation = sender.translation(in: vc.view)
+        let verticalMovement = translation.y / vc.view.bounds.height
+        let downwardMovement = fmaxf(Float(verticalMovement), 0.0)
+        let downwardMovementPercent = fminf(downwardMovement, 1.0)
+        let progress = CGFloat(downwardMovementPercent)
+
+        return progress
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialog+Keyboard.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialog+Keyboard.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialog+Keyboard.swift	(working copy)
@@ -0,0 +1,132 @@
+//
+//  PopupDialog+Keyboard.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/// This extension is designed to handle dialog positioning
+/// if a keyboard is displayed while the popup is on top
+internal extension PopupDialog {
+
+    // MARK: - Keyboard & orientation observers
+
+    /*! Add obserservers for UIKeyboard notifications */
+    internal func addObservers() {
+        NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged),
+                                                         name: UIDevice.orientationDidChangeNotification,
+                                                         object: nil)
+
+        NotificationCenter.default.addObserver(self,
+                                                         selector: #selector(keyboardWillShow),
+                                                         name: UIResponder.keyboardWillShowNotification,
+                                                         object: nil)
+
+        NotificationCenter.default.addObserver(self,
+                                                         selector: #selector(keyboardWillHide),
+                                                         name: UIResponder.keyboardWillHideNotification,
+                                                         object: nil)
+
+        NotificationCenter.default.addObserver(self,
+                                                         selector: #selector(keyboardWillChangeFrame),
+                                                         name: UIResponder.keyboardWillChangeFrameNotification,
+                                                         object: nil)
+    }
+
+    /*! Remove observers */
+    internal func removeObservers() {
+        NotificationCenter.default.removeObserver(self,
+                                                            name: UIDevice.orientationDidChangeNotification,
+                                                            object: nil)
+
+        NotificationCenter.default.removeObserver(self,
+                                                            name: UIResponder.keyboardWillShowNotification,
+                                                            object: nil)
+
+        NotificationCenter.default.removeObserver(self,
+                                                            name: UIResponder.keyboardWillHideNotification,
+                                                            object: nil)
+
+        NotificationCenter.default.removeObserver(self,
+                                                            name: UIResponder.keyboardWillChangeFrameNotification,
+                                                            object: nil)
+    }
+
+    // MARK: - Actions
+
+    /*!
+     Keyboard will show notification listener
+     - parameter notification: NSNotification
+     */
+    @objc fileprivate func keyboardWillShow(_ notification: Notification) {
+        guard isTopAndVisible else { return }
+        keyboardShown = true
+        centerPopup()
+    }
+
+    /*!
+     Keyboard will hide notification listener
+     - parameter notification: NSNotification
+     */
+    @objc fileprivate func keyboardWillHide(_ notification: Notification) {
+        guard isTopAndVisible else { return }
+        keyboardShown = false
+        centerPopup()
+    }
+
+    /*!
+     Keyboard will change frame notification listener
+     - parameter notification: NSNotification
+     */
+    @objc fileprivate func keyboardWillChangeFrame(_ notification: Notification) {
+        guard let keyboardRect = (notification as NSNotification).userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
+            return
+        }
+        keyboardHeight = keyboardRect.cgRectValue.height
+    }
+
+    /*!
+     Listen to orientation changes
+     - parameter notification: NSNotification
+     */
+    @objc fileprivate func orientationChanged(_ notification: Notification) {
+        if keyboardShown { centerPopup() }
+    }
+
+    fileprivate func centerPopup() {
+
+        // Make sure keyboard should reposition on keayboard notifications
+        guard keyboardShiftsView else { return }
+
+        // Make sure a valid keyboard height is available
+        guard let keyboardHeight = keyboardHeight else { return }
+
+        // Calculate new center of shadow background
+        let popupCenter =  keyboardShown ? keyboardHeight / -2 : 0
+
+        // Reposition and animate
+        popupContainerView.centerYConstraint?.constant = popupCenter
+        popupContainerView.pv_layoutIfNeededAnimated()
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialog.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialog.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialog.swift	(working copy)
@@ -0,0 +1,324 @@
+//
+//  PopupDialog.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/// Creates a Popup dialog similar to UIAlertController
+final public class PopupDialog: UIViewController {
+
+    // MARK: Private / Internal
+
+    /// First init flag
+    fileprivate var initialized = false
+
+    /// The completion handler
+    fileprivate var completion: (() -> Void)? = nil
+
+    /// The custom transition presentation manager
+    fileprivate var presentationManager: PresentationManager!
+
+    /// Interactor class for pan gesture dismissal
+    fileprivate lazy var interactor = InteractiveTransition()
+
+    /// Returns the controllers view
+    internal var popupContainerView: PopupDialogContainerView {
+        return view as! PopupDialogContainerView
+    }
+
+    /// The set of buttons
+    fileprivate var buttons = [PopupDialogButton]()
+
+    /// Whether keyboard has shifted view
+    internal var keyboardShown = false
+
+    /// Keyboard height
+    internal var keyboardHeight: CGFloat? = nil
+
+    // MARK: Public
+
+    /// The content view of the popup dialog
+    @objc public var viewController: UIViewController
+
+    /// Whether or not to shift view for keyboard display
+    public var keyboardShiftsView = true
+
+    // MARK: - Initializers
+
+    /*!
+     Creates a standard popup dialog with title, message and image field
+
+     - parameter title:            The dialog title
+     - parameter message:          The dialog message
+     - parameter image:            The dialog image
+     - parameter buttonAlignment:  The dialog button alignment
+     - parameter transitionStyle:  The dialog transition style
+     - parameter gestureDismissal: Indicates if dialog can be dismissed via pan gesture
+     - parameter completion:       Completion block invoked when dialog was dismissed
+
+     - returns: Popup dialog default style
+     */
+    @objc public convenience init(
+                title: String?,
+                message: String?,
+                image: UIImage? = nil,
+                buttonAlignment: NSLayoutConstraint.Axis = .vertical,
+                transitionStyle: PopupDialogTransitionStyle = .bounceUp,
+                gestureDismissal: Bool = true,
+                completion: (() -> Void)? = nil) {
+
+        // Create and configure the standard popup dialog view
+        let viewController = PopupDialogDefaultViewController()
+        viewController.titleText   = title
+        viewController.messageText = message
+        viewController.image       = image
+
+        // Call designated initializer
+        self.init(viewController: viewController, buttonAlignment: buttonAlignment, transitionStyle: transitionStyle, gestureDismissal: gestureDismissal, completion: completion)
+    }
+
+    /*!
+     Creates a popup dialog containing a custom view
+
+     - parameter viewController:   A custom view controller to be displayed
+     - parameter buttonAlignment:  The dialog button alignment
+     - parameter transitionStyle:  The dialog transition style
+     - parameter gestureDismissal: Indicates if dialog can be dismissed via pan gesture
+     - parameter completion:       Completion block invoked when dialog was dismissed
+
+     - returns: Popup dialog with a custom view controller
+     */
+    public init(
+        viewController: UIViewController,
+        buttonAlignment: NSLayoutConstraint.Axis = .vertical,
+        transitionStyle: PopupDialogTransitionStyle = .bounceUp,
+        gestureDismissal: Bool = true,
+        completion: (() -> Void)? = nil) {
+
+        self.viewController = viewController
+        self.completion = completion
+        super.init(nibName: nil, bundle: nil)
+
+        // Init the presentation manager
+        presentationManager = PresentationManager(transitionStyle: transitionStyle, interactor: interactor)
+
+        // Assign the interactor view controller
+        interactor.viewController = self
+
+        // Define presentation styles
+        transitioningDelegate = presentationManager
+        modalPresentationStyle = .custom
+
+        // Add our custom view to the container
+        if #available(iOS 9.0, *) {
+            if let stackView = popupContainerView.stackView as? UIStackView {
+                addChild(viewController)
+                stackView.insertArrangedSubview(viewController.view, at: 0)
+                viewController.didMove(toParent: self)
+            }
+        } else {
+            if let stackView = popupContainerView.stackView as? TZStackView {
+                addChild(viewController)
+                stackView.insertArrangedSubview(viewController.view, at: 0)
+                viewController.didMove(toParent: self)
+            }
+        }
+
+        // Set button alignment
+        if #available(iOS 9.0, *) {
+            if let stackView = popupContainerView.buttonStackView as? UIStackView {
+                stackView.axis = buttonAlignment
+            }
+        } else {
+            if let stackView = popupContainerView.buttonStackView as? TZStackView {
+                stackView.axis = buttonAlignment
+            }
+        }
+
+        // Allow for dialog dismissal on background tap and dialog pan gesture
+        if gestureDismissal {
+            let panRecognizer = UIPanGestureRecognizer(target: interactor, action: #selector(InteractiveTransition.handlePan))
+            popupContainerView.stackView.addGestureRecognizer(panRecognizer)
+            let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
+            tapRecognizer.cancelsTouchesInView = false
+            popupContainerView.addGestureRecognizer(tapRecognizer)
+        }
+    }
+
+    // Init with coder not implemented
+    required public init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    // MARK: - View life cycle
+
+    /// Replaces controller view with popup view
+    public override func loadView() {
+        view = PopupDialogContainerView(frame: UIScreen.main.bounds)
+    }
+
+    public override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+
+        guard !initialized else { return }
+        appendButtons()
+        addObservers()
+        initialized = true
+    }
+
+    public override func viewWillDisappear(_ animated: Bool) {
+        super.viewWillDisappear(animated)
+        removeObservers()
+    }
+
+    deinit {
+        completion?()
+        completion = nil
+    }
+
+    // MARK - Dismissal related
+
+    @objc fileprivate func handleTap(_ sender: UITapGestureRecognizer) {
+
+        // Make sure it's not a tap on the dialog but the background
+        let point = sender.location(in: popupContainerView.stackView)
+        guard !popupContainerView.stackView.point(inside: point, with: nil) else { return }
+        dismiss()
+    }
+
+    /*!
+     Dismisses the popup dialog
+     */
+    public func dismiss(_ completion: (() -> Void)? = nil) {
+        self.dismiss(animated: true) {
+            completion?()
+        }
+    }
+
+    // MARK: - Button related
+
+    /*!
+     Appends the buttons added to the popup dialog
+     to the placeholder stack view
+     */
+    fileprivate func appendButtons() {
+        // Add action to buttons
+        if #available(iOS 9.0, *) {
+            let stackView = popupContainerView.stackView as! UIStackView
+            let buttonStackView = popupContainerView.buttonStackView as! UIStackView
+            if buttons.isEmpty {
+                stackView.removeArrangedSubview(popupContainerView.buttonStackView)
+            }
+            
+            for (index, button) in buttons.enumerated() {
+                button.needsLeftSeparator = buttonStackView.axis == .horizontal && index > 0
+                buttonStackView.addArrangedSubview(button)
+                button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
+            }
+        } else {
+            let stackView = popupContainerView.stackView as! TZStackView
+            let buttonStackView = popupContainerView.buttonStackView as! TZStackView
+            if buttons.isEmpty {
+                stackView.removeArrangedSubview(popupContainerView.buttonStackView)
+            }
+            
+            for (index, button) in buttons.enumerated() {
+                button.needsLeftSeparator = buttonStackView.axis == .horizontal && index > 0
+                buttonStackView.addArrangedSubview(button)
+                button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
+            }
+        }
+    }
+
+    /*!
+     Adds a single PopupDialogButton to the Popup dialog
+     - parameter button: A PopupDialogButton instance
+     */
+    @objc public func addButton(_ button: PopupDialogButton) {
+        buttons.append(button)
+    }
+
+    /*!
+     Adds an array of PopupDialogButtons to the Popup dialog
+     - parameter buttons: A list of PopupDialogButton instances
+     */
+    @objc public func addButtons(_ buttons: [PopupDialogButton]) {
+        self.buttons += buttons
+    }
+
+    /// Calls the action closure of the button instance tapped
+    @objc fileprivate func buttonTapped(_ button: PopupDialogButton) {
+        if button.dismissOnTap {
+            dismiss() { button.buttonAction?() }
+        } else {
+            button.buttonAction?()
+        }
+    }
+
+    /*!
+     Simulates a button tap for the given index
+     Makes testing a breeze
+     - parameter index: The index of the button to tap
+     */
+    public func tapButtonWithIndex(_ index: Int) {
+        let button = buttons[index]
+        button.buttonAction?()
+    }
+}
+
+// MARK: - View proxy values
+
+extension PopupDialog {
+
+    /// The button alignment of the alert dialog
+    public var buttonAlignment: NSLayoutConstraint.Axis {
+        get {
+            if #available(iOS 9.0, *) {
+                let buttonStackView = popupContainerView.buttonStackView as! UIStackView
+                return buttonStackView.axis
+            } else {
+                let buttonStackView = popupContainerView.buttonStackView as! TZStackView
+                return buttonStackView.axis
+            }
+        }
+        set {
+            if #available(iOS 9.0, *) {
+                let buttonStackView = popupContainerView.buttonStackView as! UIStackView
+                buttonStackView.axis = newValue
+                
+            } else {
+                let buttonStackView = popupContainerView.buttonStackView as! TZStackView
+                buttonStackView.axis = newValue
+            }
+            popupContainerView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    /// The transition style
+    public var transitionStyle: PopupDialogTransitionStyle {
+        get { return presentationManager.transitionStyle }
+        set { presentationManager.transitionStyle = newValue }
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogButton.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogButton.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogButton.swift	(working copy)
@@ -0,0 +1,168 @@
+//
+//  PopupDialogButton.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/// Represents the default button for the popup dialog
+open class PopupDialogButton: UIButton {
+
+    public typealias PopupDialogButtonAction = () -> Void
+
+    // MARK: Public
+
+    /// The font and size of the button title
+    @objc open dynamic var titleFont: UIFont? {
+        get { return titleLabel?.font }
+        set { titleLabel?.font = newValue }
+    }
+    
+    /// The height of the button
+    @objc open dynamic var buttonHeight: Int
+    
+    /// The title color of the button
+    @objc open dynamic var titleColor: UIColor? {
+        get { return self.titleColor(for: UIControl.State()) }
+        set { setTitleColor(newValue, for: UIControl.State()) }
+    }
+
+    /// The background color of the button
+    @objc open dynamic var buttonColor: UIColor? {
+        get { return backgroundColor }
+        set { backgroundColor = newValue }
+    }
+
+    /// The separator color of this button
+    @objc open dynamic var separatorColor: UIColor? {
+        get { return separator.backgroundColor }
+        set {
+            separator.backgroundColor = newValue
+            leftSeparator.backgroundColor = newValue
+        }
+    }
+
+    /// Default appearance of the button
+    open var defaultTitleFont      = UIFont.systemFont(ofSize: 14)
+    open var defaultTitleColor     = UIColor(red: 0.25, green: 0.53, blue: 0.91, alpha: 1)
+    open var defaultButtonColor    = UIColor.clear
+    open var defaultSeparatorColor = UIColor(red: 0xdc/255, green: 0xdc/255, blue: 0xdc/255, alpha: 1)
+
+    /// Whether button should dismiss popup when tapped
+    open var dismissOnTap = true
+
+    /// The action called when the button is tapped
+    open fileprivate(set) var buttonAction: PopupDialogButtonAction?
+
+    // MARK: Private
+
+    fileprivate lazy var separator: UIView = {
+        let line = UIView(frame: .zero)
+        line.translatesAutoresizingMaskIntoConstraints = false
+        return line
+    }()
+
+    fileprivate lazy var leftSeparator: UIView = {
+        let line = UIView(frame: .zero)
+        line.translatesAutoresizingMaskIntoConstraints = false
+        line.alpha = 0
+        return line
+    }()
+
+    // MARK: Internal
+
+    internal var needsLeftSeparator: Bool = false {
+        didSet {
+            leftSeparator.alpha = needsLeftSeparator ? 1.0 : 0.0
+        }
+    }
+
+    // MARK: Initializers
+
+    /*!
+     Creates a button that can be added to the popup dialog
+
+     - parameter title:         The button title
+     - parameter dismisssOnTap: Whether a tap automatically dismisses the dialog
+     - parameter action:        The action closure
+
+     - returns: PopupDialogButton
+     */
+    @objc public init(title: String,
+                height: Int = 49,
+                dismissOnTap: Bool = true, action: PopupDialogButtonAction?) {
+
+        // Assign the button height
+        buttonHeight = height
+        
+        // Assign the button action
+        buttonAction = action
+
+        super.init(frame: .zero)
+
+        // Set the button title
+        setTitle(title, for: UIControl.State())
+
+        self.dismissOnTap = dismissOnTap
+
+        // Setup the views
+        setupView()
+    }
+
+    required public init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    // MARK: View setup
+
+    open func setupView() {
+
+        // Default appearance
+        setTitleColor(defaultTitleColor, for: UIControl.State())
+        titleLabel?.font              = defaultTitleFont
+        backgroundColor               = defaultButtonColor
+        separator.backgroundColor     = defaultSeparatorColor
+        leftSeparator.backgroundColor = defaultSeparatorColor
+
+        // Add and layout views
+        addSubview(separator)
+        addSubview(leftSeparator)
+
+        let views = ["separator": separator, "leftSeparator": leftSeparator, "button": self]
+        let metrics = ["buttonHeight": buttonHeight]
+        var constraints = [NSLayoutConstraint]()
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:[button(buttonHeight)]", options: [], metrics: metrics, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[separator]|", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[separator(1)]", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[leftSeparator(1)]", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[leftSeparator]|", options: [], metrics: nil, views: views)
+        NSLayoutConstraint.activate(constraints)
+    }
+
+    open override var isHighlighted: Bool {
+        didSet {
+            isHighlighted ? pv_fade(.out, 0.5) : pv_fade(.in, 1.0)
+        }
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogContainerView.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogContainerView.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogContainerView.swift	(working copy)
@@ -0,0 +1,175 @@
+//
+//  PopupDialogContainerView.swift
+//  Pods
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/// The main view of the popup dialog
+final public class PopupDialogContainerView: UIView {
+
+    // MARK: - Appearance
+
+    /// The background color of the popup dialog
+    override public dynamic var backgroundColor: UIColor? {
+        get { return container.backgroundColor }
+        set { container.backgroundColor = newValue }
+    }
+
+    /// The corner radius of the popup view
+    @objc public dynamic var cornerRadius: Float {
+        get { return Float(shadowContainer.layer.cornerRadius) }
+        set {
+            let radius = CGFloat(newValue)
+            shadowContainer.layer.cornerRadius = radius
+            container.layer.cornerRadius = radius
+        }
+    }
+
+    /// Enable / disable shadow rendering
+    @objc public dynamic var shadowEnabled: Bool {
+        get { return shadowContainer.layer.shadowRadius > 0 }
+        set { shadowContainer.layer.shadowRadius = newValue ? 5 : 0 }
+    }
+
+    /// The shadow color
+    @objc public dynamic var shadowColor: UIColor? {
+        get {
+            guard let color = shadowContainer.layer.shadowColor else {
+                return nil
+            }
+            return UIColor(cgColor: color)
+        }
+        set { shadowContainer.layer.shadowColor = newValue?.cgColor }
+    }
+
+    // MARK: - Views
+
+    /// The shadow container is the basic view of the PopupDialog
+    /// As it does not clip subviews, a shadow can be applied to it
+    internal lazy var shadowContainer: UIView = {
+        let shadowContainer = UIView(frame: .zero)
+        shadowContainer.translatesAutoresizingMaskIntoConstraints = false
+        shadowContainer.backgroundColor = UIColor.clear
+        shadowContainer.layer.shadowColor = UIColor.black.cgColor
+        shadowContainer.layer.shadowRadius = 5
+        shadowContainer.layer.shadowOpacity = 0.4
+        shadowContainer.layer.shadowOffset = CGSize(width: 0, height: 0)
+        shadowContainer.layer.cornerRadius = 4
+        return shadowContainer
+    }()
+
+    /// The container view is a child of shadowContainer and contains
+    /// all other views. It clips to bounds so cornerRadius can be set
+    internal lazy var container: UIView = {
+        let container = UIView(frame: .zero)
+        container.translatesAutoresizingMaskIntoConstraints = false
+        container.backgroundColor = UIColor.white
+        container.clipsToBounds = true
+        container.layer.cornerRadius = 4
+        return container
+    }()
+
+    // The container stack view for buttons
+    internal lazy var buttonStackView: UIView = {
+        if #available(iOS 9.0, *) {
+            let buttonStackView = UIStackView()
+            buttonStackView.translatesAutoresizingMaskIntoConstraints = false
+            buttonStackView.distribution = .fillEqually
+            buttonStackView.spacing = 0
+            return buttonStackView
+        } else {
+            let buttonStackView = TZStackView()
+            buttonStackView.translatesAutoresizingMaskIntoConstraints = false
+            buttonStackView.distribution = .fillEqually
+            buttonStackView.spacing = 0
+            return buttonStackView
+        }
+    }()
+
+    // The main stack view, containing all relevant views
+    internal lazy var stackView: UIView = {
+        if #available(iOS 9.0, *) {
+            let stackView = UIStackView(arrangedSubviews: [self.buttonStackView])
+            stackView.translatesAutoresizingMaskIntoConstraints = false
+            stackView.axis = .vertical
+            stackView.spacing = 0
+            return stackView
+        } else {
+            let stackView = TZStackView(arrangedSubviews: [self.buttonStackView])
+            stackView.translatesAutoresizingMaskIntoConstraints = false
+            stackView.axis = .vertical
+            stackView.spacing = 0
+            return stackView
+        }
+    }()
+
+    // MARK: - Constraints
+
+    /// The center constraint of the shadow container
+    internal var centerYConstraint: NSLayoutConstraint? = nil
+
+    // MARK: - Initializers
+
+    internal override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupViews()
+    }
+
+    required public init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    // MARK: - View setup
+
+    internal func setupViews() {
+
+        // Add views
+        addSubview(shadowContainer)
+        shadowContainer.addSubview(container)
+        container.addSubview(stackView)
+
+        // Layout views
+        let views = ["shadowContainer": shadowContainer, "container": container, "stackView": stackView]
+        var constraints = [NSLayoutConstraint]()
+
+        // Shadow container constraints
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-(>=10,==20@900)-[shadowContainer(<=340,>=300)]-(>=10,==20@900)-|", options: [], metrics: nil, views: views)
+        constraints += [NSLayoutConstraint(item: shadowContainer, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0)]
+        centerYConstraint = NSLayoutConstraint(item: shadowContainer, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0)
+        constraints.append(centerYConstraint!)
+
+        // Container constraints
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[container]|", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[container]|", options: [], metrics: nil, views: views)
+
+        // Main stack view constraints
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[stackView]|", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[stackView]|", options: [], metrics: nil, views: views)
+
+        // Activate constraints
+        NSLayoutConstraint.activate(constraints)
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultButtons.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultButtons.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultButtons.swift	(working copy)
@@ -0,0 +1,54 @@
+//
+//  PopupDialogDefaultButtons.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+// MARK: Default button
+
+/// Represents the default button for the popup dialog
+@objc public final class DefaultButton: PopupDialogButton {}
+
+// MARK: Cancel button
+
+/// Represents a cancel button for the popup dialog
+public final class CancelButton: PopupDialogButton {
+
+    override public func setupView() {
+        defaultTitleColor = UIColor.lightGray
+        super.setupView()
+    }
+}
+
+// MARK: destructive button
+
+/// Represents a destructive button for the popup dialog
+public final class DestructiveButton: PopupDialogButton {
+
+    override public func setupView() {
+        defaultTitleColor = UIColor.red
+        super.setupView()
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultView.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultView.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultView.swift	(working copy)
@@ -0,0 +1,145 @@
+//
+//  PopupDialogView.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/// The main view of the popup dialog
+final public class PopupDialogDefaultView: UIView {
+
+    // MARK: - Appearance
+
+    /// The font and size of the title label
+    @objc public dynamic var titleFont: UIFont {
+        get { return titleLabel.font }
+        set { titleLabel.font = newValue }
+    }
+
+    /// The color of the title label
+    @objc public dynamic var titleColor: UIColor? {
+        get { return titleLabel.textColor }
+        set { titleLabel.textColor = newValue }
+    }
+
+    /// The text alignment of the title label
+    @objc public dynamic var titleTextAlignment: NSTextAlignment {
+        get { return titleLabel.textAlignment }
+        set { titleLabel.textAlignment = newValue }
+    }
+
+    /// The font and size of the body label
+    @objc public dynamic var messageFont: UIFont {
+        get { return messageLabel.font }
+        set { messageLabel.font = newValue }
+    }
+
+    /// The color of the message label
+    @objc public dynamic var messageColor: UIColor? {
+        get { return messageLabel.textColor }
+        set { messageLabel.textColor = newValue}
+    }
+
+    /// The text alignment of the message label
+    @objc public dynamic var messageTextAlignment: NSTextAlignment {
+        get { return messageLabel.textAlignment }
+        set { messageLabel.textAlignment = newValue }
+    }
+
+    // MARK: - Views
+
+    /// The view that will contain the image, if set
+    internal lazy var imageView: UIImageView = {
+        let imageView = UIImageView(frame: .zero)
+        imageView.translatesAutoresizingMaskIntoConstraints = false
+        imageView.contentMode = .scaleAspectFit
+        imageView.clipsToBounds = true
+        return imageView
+    }()
+
+    /// The title label of the dialog
+    internal lazy var titleLabel: UILabel = {
+        let titleLabel = UILabel(frame: .zero)
+        titleLabel.translatesAutoresizingMaskIntoConstraints = false
+        titleLabel.numberOfLines = 0
+        titleLabel.textAlignment = .center
+        titleLabel.textColor = UIColor(white: 0.4, alpha: 1)
+        titleLabel.font = UIFont.boldSystemFont(ofSize: 14)
+        return titleLabel
+    }()
+
+    /// The message label of the dialog
+    internal lazy var messageLabel: UILabel = {
+        let messageLabel = UILabel(frame: .zero)
+        messageLabel.translatesAutoresizingMaskIntoConstraints = false
+        messageLabel.numberOfLines = 0
+        messageLabel.textAlignment = .center
+        messageLabel.textColor = UIColor(white: 0.6, alpha: 1)
+        messageLabel.font = UIFont.systemFont(ofSize: 14)
+        return messageLabel
+    }()
+    
+    /// The height constraint of the image view, 0 by default
+    internal var imageHeightConstraint: NSLayoutConstraint?
+
+    // MARK: - Initializers
+
+    internal override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupViews()
+    }
+
+    required public init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    // MARK: - View setup
+
+    internal func setupViews() {
+
+        // Self setup
+        translatesAutoresizingMaskIntoConstraints = false
+
+        // Add views
+        addSubview(imageView)
+        addSubview(titleLabel)
+        addSubview(messageLabel)
+
+        // Layout views
+        let views = ["imageView": imageView, "titleLabel": titleLabel, "messageLabel": messageLabel] as [String : Any]
+        var constraints = [NSLayoutConstraint]()
+
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[imageView]|", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-(==20@900)-[titleLabel]-(==20@900)-|", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|-(==20@900)-[messageLabel]-(==20@900)-|", options: [], metrics: nil, views: views)
+        constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[imageView]-(==30@900)-[titleLabel]-(==30@900)-[messageLabel]-(==25@900)-|", options: [], metrics: nil, views: views)
+        
+        // ImageView height constraint
+        imageHeightConstraint = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: imageView, attribute: .height, multiplier: 0, constant: 0)
+        constraints.append(imageHeightConstraint!)
+
+        // Activate constraints
+        NSLayoutConstraint.activate(constraints)
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultViewController.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultViewController.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogDefaultViewController.swift	(working copy)
@@ -0,0 +1,133 @@
+//
+//  PopupDialogDefaultViewController.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import UIKit
+
+final public class PopupDialogDefaultViewController: UIViewController {
+
+    public var standardView: PopupDialogDefaultView {
+       return view as! PopupDialogDefaultView
+    }
+
+    override public func loadView() {
+        super.loadView()
+        view = PopupDialogDefaultView(frame: .zero)
+    }
+}
+
+public extension PopupDialogDefaultViewController {
+
+    // MARK: - Setter / Getter
+
+    // MARK: Content
+
+    /// The dialog image
+    public var image: UIImage? {
+        get { return standardView.imageView.image }
+        set {
+            standardView.imageView.image = newValue
+            standardView.imageHeightConstraint?.constant = standardView.imageView.pv_heightForImageView()
+        }
+    }
+
+    /// The title text of the dialog
+    public var titleText: String? {
+        get { return standardView.titleLabel.text }
+        set {
+            standardView.titleLabel.text = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    /// The message text of the dialog
+    public var messageText: String? {
+        get { return standardView.messageLabel.text }
+        set {
+            standardView.messageLabel.text = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    // MARK: Appearance
+
+    /// The font and size of the title label
+    @objc public dynamic var titleFont: UIFont {
+        get { return standardView.titleFont }
+        set {
+            standardView.titleFont = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    /// The color of the title label
+    @objc public dynamic var titleColor: UIColor? {
+        get { return standardView.titleLabel.textColor }
+        set {
+            standardView.titleColor = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    /// The text alignment of the title label
+    @objc public dynamic var titleTextAlignment: NSTextAlignment {
+        get { return standardView.titleTextAlignment }
+        set {
+            standardView.titleTextAlignment = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    /// The font and size of the body label
+    @objc public dynamic var messageFont: UIFont {
+        get { return standardView.messageFont}
+        set {
+            standardView.messageFont = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    /// The color of the message label
+    @objc public dynamic var messageColor: UIColor? {
+        get { return standardView.messageColor }
+        set {
+            standardView.messageColor = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+
+    /// The text alignment of the message label
+    @objc public dynamic var messageTextAlignment: NSTextAlignment {
+        get { return standardView.messageTextAlignment }
+        set {
+            standardView.messageTextAlignment = newValue
+            standardView.pv_layoutIfNeededAnimated()
+        }
+    }
+    
+    public override func viewDidLayoutSubviews() {
+        super.viewDidLayoutSubviews()
+        standardView.imageHeightConstraint?.constant = standardView.imageView.pv_heightForImageView()
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogOverlayView.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogOverlayView.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PopupDialogOverlayView.swift	(working copy)
@@ -0,0 +1,111 @@
+//
+//  PopupDialogOverlayView.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import UIKit
+
+/// The (blurred) overlay view below the popup dialog
+final public class PopupDialogOverlayView: UIView {
+
+    // MARK: - Appearance
+
+    ///  The blur radius of the overlay view
+    @objc public dynamic var blurRadius: Float {
+        get { return Float(blurView.blurRadius) }
+        set { blurView.blurRadius = CGFloat(newValue) }
+    }
+
+    /// Turns the blur of the overlay view on or off
+    @objc public dynamic var blurEnabled: Bool {
+        get { return blurView.isBlurEnabled }
+        set {
+            blurView.isBlurEnabled = newValue
+            blurView.alpha = newValue ? 1 : 0
+        }
+    }
+
+    /// Whether the blur view should allow for
+    /// dynamic rendering of the background
+    @objc public dynamic var liveBlur: Bool {
+        get { return blurView.isDynamic }
+        set { return blurView.isDynamic = newValue }
+    }
+
+    /// The background color of the overlay view
+    @objc public dynamic var color: UIColor? {
+        get { return overlay.backgroundColor }
+        set { overlay.backgroundColor = newValue }
+    }
+
+    /// The opacity of the overay view
+    @objc public dynamic var opacity: Float {
+        get { return Float(overlay.alpha) }
+        set { overlay.alpha = CGFloat(newValue) }
+    }
+
+    // MARK: - Views
+
+    internal lazy var blurView: FXBlurView = {
+        let blurView = FXBlurView(frame: .zero)
+        blurView.blurRadius = 8
+        blurView.isDynamic = false
+        blurView.tintColor = UIColor.clear
+        blurView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+        return blurView
+    }()
+
+    internal lazy var overlay: UIView = {
+        let overlay = UIView(frame: .zero)
+        overlay.backgroundColor = UIColor.black
+        overlay.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+        overlay.alpha = 0.7
+        return overlay
+    }()
+
+    // MARK: - Inititalizers
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupView()
+    }
+
+    required public init?(coder aDecoder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    // MARK: - View setup
+
+    fileprivate func setupView() {
+
+        // Self appearance
+        self.autoresizingMask = [.flexibleHeight, .flexibleWidth]
+        self.backgroundColor = UIColor.clear
+        self.alpha = 0
+
+        // Add subviews
+        addSubview(blurView)
+        addSubview(overlay)
+    }
+
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PresentationController.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PresentationController.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PresentationController.swift	(working copy)
@@ -0,0 +1,61 @@
+//
+//  PopupDialogPresentationController.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+final internal class PresentationController: UIPresentationController {
+
+    fileprivate lazy var overlay: PopupDialogOverlayView = {
+        return PopupDialogOverlayView(frame: .zero)
+    }()
+
+    override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
+        super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
+        overlay.blurView.underlyingView = presentingViewController?.view
+        overlay.frame = (presentingViewController?.view.bounds)!
+    }
+
+    override func presentationTransitionWillBegin() {
+        overlay.frame = containerView!.bounds
+        containerView!.insertSubview(overlay, at: 0)
+
+        presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (coordinatorContext) -> Void in
+            self.overlay.alpha = 1.0
+        }, completion: nil)
+    }
+
+    override func dismissalTransitionWillBegin() {
+        presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (coordinatorContext) -> Void in
+            self.overlay.alpha = 0.0
+        }, completion: nil)
+    }
+
+    override func containerViewWillLayoutSubviews() {
+        presentedView!.frame = frameOfPresentedViewInContainerView
+        overlay.blurView.setNeedsDisplay()
+    }
+
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PresentationManager.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PresentationManager.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/PresentationManager.swift	(working copy)
@@ -0,0 +1,86 @@
+//
+//  PopupDialogPresentationManager.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+final internal class PresentationManager: NSObject, UIViewControllerTransitioningDelegate {
+
+    var transitionStyle: PopupDialogTransitionStyle
+    var interactor: InteractiveTransition
+
+    init(transitionStyle: PopupDialogTransitionStyle, interactor: InteractiveTransition) {
+        self.transitionStyle = transitionStyle
+        self.interactor = interactor
+        super.init()
+    }
+
+    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
+        let presentationController = PresentationController(presentedViewController: presented, presenting: source)
+        return presentationController
+    }
+
+    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
+
+        var transition: TransitionAnimator
+        switch transitionStyle {
+        case .bounceUp:
+            transition = BounceUpTransition(direction: .in)
+        case .bounceDown:
+            transition = BounceDownTransition(direction: .in)
+        case .zoomIn:
+            transition = ZoomTransition(direction: .in)
+        case .fadeIn:
+            transition = FadeTransition(direction: .in)
+        }
+
+        return transition
+    }
+
+    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
+
+        if interactor.hasStarted || interactor.shouldFinish {
+            return DismissInteractiveTransition()
+        }
+
+        var transition: TransitionAnimator
+        switch transitionStyle {
+        case .bounceUp:
+            transition = BounceUpTransition(direction: .out)
+        case .bounceDown:
+            transition = BounceDownTransition(direction: .out)
+        case .zoomIn:
+            transition = ZoomTransition(direction: .out)
+        case .fadeIn:
+            transition = FadeTransition(direction: .out)
+        }
+
+        return transition
+    }
+
+    func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
+        return interactor.hasStarted ? interactor : nil
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZSpacerView.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZSpacerView.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZSpacerView.swift	(working copy)
@@ -0,0 +1,13 @@
+//
+//  TZSpacerView.swift
+//  TZStackView
+//
+//  Created by Tom van Zummeren on 15/06/15.
+//  Copyright © 2015 Tom van Zummeren. All rights reserved.
+//
+
+import UIKit
+
+public class TZSpacerView: UIView {
+	
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackView.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackView.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackView.swift	(working copy)
@@ -0,0 +1,608 @@
+//
+//  TZStackView.swift
+//  TZStackView
+//
+//  Created by Tom van Zummeren on 10/06/15.
+//  Copyright © 2015 Tom van Zummeren. All rights reserved.
+//
+
+import UIKit
+
+struct TZAnimationDidStopQueueEntry: Equatable {
+    let view: UIView
+    let hidden: Bool
+}
+
+func ==(lhs: TZAnimationDidStopQueueEntry, rhs: TZAnimationDidStopQueueEntry) -> Bool {
+    return lhs.view === rhs.view
+}
+
+public class TZStackView: UIView {
+
+    public var distribution: TZStackViewDistribution = .fill {
+        didSet {
+            setNeedsUpdateConstraints()
+        }
+    }
+
+    public var axis: NSLayoutConstraint.Axis = .horizontal {
+        didSet {
+            setNeedsUpdateConstraints()
+        }
+    }
+    
+    public var alignment: TZStackViewAlignment = .fill
+
+    public var spacing: CGFloat = 0
+    
+    public var layoutMarginsRelativeArrangement = false
+
+    public private(set) var arrangedSubviews: [UIView] = [] {
+        didSet {
+            setNeedsUpdateConstraints()
+            registerHiddenListeners(oldValue)
+        }
+    }
+
+    private var kvoContext = UInt8()
+
+    private var stackViewConstraints = [NSLayoutConstraint]()
+    private var subviewConstraints = [NSLayoutConstraint]()
+
+    private var spacerViews = [UIView]()
+    
+    private var animationDidStopQueueEntries = [TZAnimationDidStopQueueEntry]()
+    
+    private var registeredKvoSubviews = [UIView]()
+    
+    private var animatingToHiddenViews = [UIView]()
+
+    public init(arrangedSubviews: [UIView] = []) {
+        super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
+        for arrangedSubview in arrangedSubviews {
+            arrangedSubview.translatesAutoresizingMaskIntoConstraints = false
+            addSubview(arrangedSubview)
+        }
+
+        // Closure to invoke didSet()
+        { self.arrangedSubviews = arrangedSubviews }()
+    }
+    
+    deinit {
+        // This removes `hidden` value KVO observers using didSet()
+        { self.arrangedSubviews = [] }()
+    }
+    
+    private func registerHiddenListeners(_ previousArrangedSubviews: [UIView]) {
+        for subview in previousArrangedSubviews {
+            self.removeHiddenListener(subview)
+        }
+
+        for subview in arrangedSubviews {
+            self.addHiddenListener(subview)
+        }
+    }
+    
+    private func addHiddenListener(_ view: UIView) {
+        view.addObserver(self, forKeyPath: "hidden", options: [.old, .new], context: &kvoContext)
+        registeredKvoSubviews.append(view)
+    }
+    
+    private func removeHiddenListener(_ view: UIView) {
+        if let index = registeredKvoSubviews.index(of: view) {
+            view.removeObserver(self, forKeyPath: "hidden", context: &kvoContext)
+            registeredKvoSubviews.remove(at: index)
+        }
+    }
+
+    public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
+        if let view = object as? UIView, let change = change, keyPath == "hidden" {
+            let hidden = view.isHidden
+            let previousValue = change[.oldKey] as! Bool
+            if hidden == previousValue {
+                return
+            }
+            if hidden {
+                animatingToHiddenViews.append(view)
+            }
+            // Perform the animation
+            setNeedsUpdateConstraints()
+            setNeedsLayout()
+            layoutIfNeeded()
+            
+            removeHiddenListener(view)
+            view.isHidden = false
+
+            if let _ = view.layer.animationKeys() {
+                UIView.setAnimationDelegate(self)
+                animationDidStopQueueEntries.insert(TZAnimationDidStopQueueEntry(view: view, hidden: hidden), at: 0)
+                UIView.setAnimationDidStop(#selector(TZStackView.hiddenAnimationStopped))
+            } else {
+                didFinishSettingHiddenValue(view, hidden: hidden)
+            }
+        }
+    }
+    
+    private func didFinishSettingHiddenValue(_ arrangedSubview: UIView, hidden: Bool) {
+        arrangedSubview.isHidden = hidden
+        if let index = animatingToHiddenViews.index(of: arrangedSubview) {
+            animatingToHiddenViews.remove(at: index)
+        }
+        addHiddenListener(arrangedSubview)
+    }
+
+    @objc func hiddenAnimationStopped() {
+        var queueEntriesToRemove = [TZAnimationDidStopQueueEntry]()
+        for entry in animationDidStopQueueEntries {
+            let view = entry.view
+            if view.layer.animationKeys() == nil {
+                didFinishSettingHiddenValue(view, hidden: entry.hidden)
+                queueEntriesToRemove.append(entry)
+            }
+        }
+        for entry in queueEntriesToRemove {
+            if let index = animationDidStopQueueEntries.index(of: entry) {
+                animationDidStopQueueEntries.remove(at: index)
+            }
+        }
+    }
+    
+    public func addArrangedSubview(_ view: UIView) {
+        view.translatesAutoresizingMaskIntoConstraints = false
+        addSubview(view)
+        arrangedSubviews.append(view)
+    }
+    
+    public func removeArrangedSubview(_ view: UIView) {
+        if let index = arrangedSubviews.index(of: view) {
+            arrangedSubviews.remove(at: index)
+        }
+    }
+
+    public func insertArrangedSubview(_ view: UIView, at stackIndex: Int) {
+        view.translatesAutoresizingMaskIntoConstraints = false
+        addSubview(view)
+        arrangedSubviews.insert(view, at: stackIndex)
+    }
+
+    override public func willRemoveSubview(_ subview: UIView) {
+        removeArrangedSubview(subview)
+    }
+
+    override public func updateConstraints() {
+        removeConstraints(stackViewConstraints)
+        stackViewConstraints.removeAll()
+
+        for arrangedSubview in arrangedSubviews {
+            arrangedSubview.removeConstraints(subviewConstraints)
+        }
+        subviewConstraints.removeAll()
+        for arrangedSubview in arrangedSubviews {
+            
+            if alignment != .fill {
+                let guideConstraint: NSLayoutConstraint
+                switch axis {
+                case .horizontal:
+                    guideConstraint = constraint(item: arrangedSubview, attribute: .height, toItem: nil, attribute: .notAnAttribute, constant: 0, priority: 25)
+                case .vertical:
+                    guideConstraint = constraint(item: arrangedSubview, attribute: .width, toItem: nil, attribute: .notAnAttribute, constant: 0, priority: 25)
+                }
+                subviewConstraints.append(guideConstraint)
+                arrangedSubview.addConstraint(guideConstraint)
+            }
+            
+            if isHidden(arrangedSubview) {
+                let hiddenConstraint: NSLayoutConstraint
+                switch axis {
+                case .horizontal:
+                    hiddenConstraint = constraint(item: arrangedSubview, attribute: .width, toItem: nil, attribute: .notAnAttribute, constant: 0)
+                case .vertical:
+                    hiddenConstraint = constraint(item: arrangedSubview, attribute: .height, toItem: nil, attribute: .notAnAttribute, constant: 0)
+                }
+                subviewConstraints.append(hiddenConstraint)
+                arrangedSubview.addConstraint(hiddenConstraint)
+            }
+        }
+        
+        for spacerView in spacerViews {
+            spacerView.removeFromSuperview()
+        }
+        spacerViews.removeAll()
+        
+        if arrangedSubviews.count > 0 {
+            
+            let visibleArrangedSubviews = arrangedSubviews.filter({!self.isHidden($0)})
+            
+            switch distribution {
+            case .fillEqually, .fill, .fillProportionally:
+                if alignment != .fill || layoutMarginsRelativeArrangement {
+                    _ = addSpacerView()
+                }
+
+                stackViewConstraints += createMatchEdgesContraints(arrangedSubviews)
+                stackViewConstraints += createFirstAndLastViewMatchEdgesContraints()
+                
+                if alignment == .firstBaseline && axis == .horizontal {
+                    stackViewConstraints.append(constraint(item: self, attribute: .height, toItem: nil, attribute: .notAnAttribute, priority: 49))
+                }
+
+                if distribution == .fillEqually {
+                    stackViewConstraints += createFillEquallyConstraints(arrangedSubviews)
+                }
+                if distribution == .fillProportionally {
+                    stackViewConstraints += createFillProportionallyConstraints(arrangedSubviews)
+                }
+                
+                stackViewConstraints += createFillConstraints(arrangedSubviews, constant: spacing)
+            case .equalSpacing:
+                var views = [UIView]()
+                var index = 0
+                for arrangedSubview in arrangedSubviews {
+                    if isHidden(arrangedSubview) {
+                        continue
+                    }
+                    if index > 0 {
+                        views.append(addSpacerView())
+                    }
+                    views.append(arrangedSubview)
+                    index += 1
+                }
+                if spacerViews.count == 0 {
+                    _ = addSpacerView()
+                }
+                
+                stackViewConstraints += createMatchEdgesContraints(arrangedSubviews)
+                stackViewConstraints += createFirstAndLastViewMatchEdgesContraints()
+                
+                switch axis {
+                case .horizontal:
+                    stackViewConstraints.append(constraint(item: self, attribute: .width, toItem: nil, attribute: .notAnAttribute, priority: 49))
+                    if alignment == .firstBaseline {
+                        stackViewConstraints.append(constraint(item: self, attribute: .height, toItem: nil, attribute: .notAnAttribute, priority: 49))
+                    }
+                case .vertical:
+                    stackViewConstraints.append(constraint(item: self, attribute: .height, toItem: nil, attribute: .notAnAttribute, priority: 49))
+                }
+
+                stackViewConstraints += createFillConstraints(views, constant: 0)
+                stackViewConstraints += createFillEquallyConstraints(spacerViews)
+                stackViewConstraints += createFillConstraints(arrangedSubviews, relatedBy: .greaterThanOrEqual, constant: spacing)
+            case .equalCentering:
+                for (index, _) in visibleArrangedSubviews.enumerated() {
+                    if index > 0 {
+                        _ = addSpacerView()
+                    }
+                }
+                if spacerViews.count == 0 {
+                    _ = addSpacerView()
+                }
+                
+                stackViewConstraints += createMatchEdgesContraints(arrangedSubviews)
+                stackViewConstraints += createFirstAndLastViewMatchEdgesContraints()
+                
+                switch axis {
+                case .horizontal:
+                    stackViewConstraints.append(constraint(item: self, attribute: .width, toItem: nil, attribute: .notAnAttribute, priority: 49))
+                    if alignment == .firstBaseline {
+                        stackViewConstraints.append(constraint(item: self, attribute: .height, toItem: nil, attribute: .notAnAttribute, priority: 49))
+                    }
+                case .vertical:
+                    stackViewConstraints.append(constraint(item: self, attribute: .height, toItem: nil, attribute: .notAnAttribute, priority: 49))
+                }
+
+                var previousArrangedSubview: UIView?
+                for (index, arrangedSubview) in visibleArrangedSubviews.enumerated() {
+                    if let previousArrangedSubview = previousArrangedSubview {
+                        let spacerView = spacerViews[index - 1]
+                        
+                        switch axis {
+                        case .horizontal:
+                            stackViewConstraints.append(constraint(item: previousArrangedSubview, attribute: .centerX, toItem: spacerView, attribute: .leading))
+                            stackViewConstraints.append(constraint(item: arrangedSubview, attribute: .centerX, toItem: spacerView, attribute: .trailing))
+                        case .vertical:
+                            stackViewConstraints.append(constraint(item: previousArrangedSubview, attribute: .centerY, toItem: spacerView, attribute: .top))
+                            stackViewConstraints.append(constraint(item: arrangedSubview, attribute: .centerY, toItem: spacerView, attribute: .bottom))
+                        }
+                    }
+                    previousArrangedSubview = arrangedSubview
+                }
+
+                stackViewConstraints += createFillEquallyConstraints(spacerViews, priority: 150)
+                stackViewConstraints += createFillConstraints(arrangedSubviews, relatedBy: .greaterThanOrEqual, constant: spacing)
+            }
+            
+            if spacerViews.count > 0 {
+                stackViewConstraints += createSurroundingSpacerViewConstraints(spacerViews[0], views: visibleArrangedSubviews)
+            }
+
+            if layoutMarginsRelativeArrangement {
+                if spacerViews.count > 0 {
+                    stackViewConstraints.append(constraint(item: self, attribute: .bottomMargin, toItem: spacerViews[0], attribute: .bottom))
+                    stackViewConstraints.append(constraint(item: self, attribute: .leftMargin, toItem: spacerViews[0], attribute: .left))
+                    stackViewConstraints.append(constraint(item: self, attribute: .rightMargin, toItem: spacerViews[0], attribute: .right))
+                    stackViewConstraints.append(constraint(item: self, attribute: .topMargin, toItem: spacerViews[0], attribute: .top))
+                }
+            }
+            addConstraints(stackViewConstraints)
+        }
+
+        super.updateConstraints()
+    }
+
+    required public init(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)!
+    }
+    
+    private func addSpacerView() -> TZSpacerView {
+        let spacerView = TZSpacerView()
+        spacerView.translatesAutoresizingMaskIntoConstraints = false
+        
+        spacerViews.append(spacerView)
+        insertSubview(spacerView, at: 0)
+        return spacerView
+    }
+    
+    private func createSurroundingSpacerViewConstraints(_ spacerView: UIView, views: [UIView]) -> [NSLayoutConstraint] {
+        if alignment == .fill {
+            return []
+        }
+        
+        var topPriority: Float = 1000
+        var topRelation: NSLayoutConstraint.Relation = .lessThanOrEqual
+        
+        var bottomPriority: Float = 1000
+        var bottomRelation: NSLayoutConstraint.Relation = .greaterThanOrEqual
+        
+        if alignment == .top || alignment == .leading {
+            topPriority = 999.5
+            topRelation = .equal
+        }
+        
+        if alignment == .bottom || alignment == .trailing {
+            bottomPriority = 999.5
+            bottomRelation = .equal
+        }
+        
+        var constraints = [NSLayoutConstraint]()
+        for view in views {
+            switch axis {
+            case .horizontal:
+                constraints.append(constraint(item: spacerView, attribute: .top, relatedBy: topRelation, toItem: view, priority: topPriority))
+                constraints.append(constraint(item: spacerView, attribute: .bottom, relatedBy: bottomRelation, toItem: view, priority: bottomPriority))
+            case .vertical:
+                constraints.append(constraint(item: spacerView, attribute: .leading, relatedBy: topRelation, toItem: view, priority: topPriority))
+                constraints.append(constraint(item: spacerView, attribute: .trailing, relatedBy: bottomRelation, toItem: view, priority: bottomPriority))
+            }
+        }
+        switch axis {
+        case .horizontal:
+            constraints.append(constraint(item: spacerView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, constant: 0, priority: 51))
+        case .vertical:
+            constraints.append(constraint(item: spacerView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, constant: 0, priority: 51))
+        }
+        return constraints
+    }
+    
+    private func createFillProportionallyConstraints(_ views: [UIView]) -> [NSLayoutConstraint] {
+        var constraints = [NSLayoutConstraint]()
+
+        var totalSize: CGFloat = 0
+        var totalCount = 0
+        for arrangedSubview in views {
+            if isHidden(arrangedSubview) {
+                continue
+            }
+            switch axis {
+            case .horizontal:
+                totalSize += arrangedSubview.intrinsicContentSize.width
+            case .vertical:
+                totalSize += arrangedSubview.intrinsicContentSize.height
+            }
+            totalCount += 1
+        }
+        totalSize += (CGFloat(totalCount - 1) * spacing)
+        
+        var priority: Float = 1000
+        let countDownPriority = (views.filter({!self.isHidden($0)}).count > 1)
+        for arrangedSubview in views {
+            if countDownPriority {
+                priority -= 1
+            }
+            
+            if isHidden(arrangedSubview) {
+                continue
+            }
+            switch axis {
+            case .horizontal:
+                let multiplier = arrangedSubview.intrinsicContentSize.width / totalSize
+                constraints.append(constraint(item: arrangedSubview, attribute: .width, toItem: self, multiplier: multiplier, priority: priority))
+            case .vertical:
+                let multiplier = arrangedSubview.intrinsicContentSize.height / totalSize
+                constraints.append(constraint(item: arrangedSubview, attribute: .height, toItem: self, multiplier: multiplier, priority: priority))
+            }
+        }
+        
+        return constraints
+    }
+    
+    // Matchs all Width or Height attributes of all given views
+    private func createFillEquallyConstraints(_ views: [UIView], priority: Float = 1000) -> [NSLayoutConstraint] {
+        switch axis {
+        case .horizontal:
+            return equalAttributes(views: views.filter({ !self.isHidden($0) }), attribute: .width, priority: priority)
+            
+        case .vertical:
+            return equalAttributes(views: views.filter({ !self.isHidden($0) }), attribute: .height, priority: priority)
+        }
+    }
+    
+    // Chains together the given views using Leading/Trailing or Top/Bottom
+    private func createFillConstraints(_ views: [UIView], priority: Float = 1000, relatedBy relation: NSLayoutConstraint.Relation = .equal, constant: CGFloat) -> [NSLayoutConstraint] {
+        var constraints = [NSLayoutConstraint]()
+
+        var previousView: UIView?
+        for view in views {
+            if let previousView = previousView {
+                var c: CGFloat = 0
+                if !isHidden(previousView) && !isHidden(view) {
+                    c = constant
+                } else if isHidden(previousView) && !isHidden(view) && views.first != previousView {
+                    c = (constant / 2)
+                } else if isHidden(view) && !isHidden(previousView) && views.last != view {
+                    c = (constant / 2)
+                }
+                switch axis {
+                case .horizontal:
+                    constraints.append(constraint(item: view, attribute: .leading, relatedBy: relation, toItem: previousView, attribute: .trailing, constant: c, priority: priority))
+                    
+                case .vertical:
+                    constraints.append(constraint(item: view, attribute: .top, relatedBy: relation, toItem: previousView, attribute: .bottom, constant: c, priority: priority))
+                }
+            }
+            previousView = view
+        }
+        return constraints
+    }
+    
+    // Matches all Bottom/Top or Leading Trailing constraints of te given views and matches those attributes of the first/last view to the container
+    private func createMatchEdgesContraints(_ views: [UIView]) -> [NSLayoutConstraint] {
+        var constraints = [NSLayoutConstraint]()
+
+        switch axis {
+        case .horizontal:
+            switch alignment {
+            case .fill:
+                constraints += equalAttributes(views: views, attribute: .bottom)
+                constraints += equalAttributes(views: views, attribute: .top)
+            case .center:
+                constraints += equalAttributes(views: views, attribute: .centerY)
+            case .leading, .top:
+                constraints += equalAttributes(views: views, attribute: .top)
+            case .trailing, .bottom:
+                constraints += equalAttributes(views: views, attribute: .bottom)
+            case .firstBaseline:
+                constraints += equalAttributes(views: views, attribute: .firstBaseline)
+            }
+            
+        case .vertical:
+            switch alignment {
+            case .fill:
+                constraints += equalAttributes(views: views, attribute: .leading)
+                constraints += equalAttributes(views: views, attribute: .trailing)
+            case .center:
+                constraints += equalAttributes(views: views, attribute: .centerX)
+            case .leading, .top:
+                constraints += equalAttributes(views: views, attribute: .leading)
+            case .trailing, .bottom:
+                constraints += equalAttributes(views: views, attribute: .trailing)
+            case .firstBaseline:
+                constraints += []
+            }
+        }
+        return constraints
+    }
+    
+    private func createFirstAndLastViewMatchEdgesContraints() -> [NSLayoutConstraint] {
+        
+        var constraints = [NSLayoutConstraint]()
+        
+        let visibleViews = arrangedSubviews.filter({!self.isHidden($0)})
+        let firstView = visibleViews.first
+        let lastView = visibleViews.last
+
+        var topView = arrangedSubviews.first!
+        var bottomView = arrangedSubviews.first!
+        if spacerViews.count > 0 {
+            if alignment == .center {
+                topView = spacerViews[0]
+                bottomView = spacerViews[0]
+            } else if alignment == .top || alignment == .leading {
+                bottomView = spacerViews[0]
+            } else if alignment == .bottom || alignment == .trailing {
+                topView = spacerViews[0]
+            } else if alignment == .firstBaseline {
+                switch axis {
+                case .horizontal:
+                    bottomView = spacerViews[0]
+                case .vertical:
+                    topView = spacerViews[0]
+                    bottomView = spacerViews[0]
+                }
+            }
+        }
+        
+        let firstItem = layoutMarginsRelativeArrangement ? spacerViews[0] : self
+
+        switch axis {
+        case .horizontal:
+            if let firstView = firstView {
+                constraints.append(constraint(item: firstItem, attribute: .leading, toItem: firstView))
+            }
+            if let lastView = lastView {
+                constraints.append(constraint(item: firstItem, attribute: .trailing, toItem: lastView))
+            }
+            
+            constraints.append(constraint(item: firstItem, attribute: .top, toItem: topView))
+            constraints.append(constraint(item: firstItem, attribute: .bottom, toItem: bottomView))
+
+            if alignment == .center {
+                constraints.append(constraint(item: firstItem, attribute: .centerY, toItem: arrangedSubviews.first!))
+            }
+        case .vertical:
+            if let firstView = firstView {
+                constraints.append(constraint(item: firstItem, attribute: .top, toItem: firstView))
+            }
+            if let lastView = lastView {
+                constraints.append(constraint(item: firstItem, attribute: .bottom, toItem: lastView))
+            }
+
+            constraints.append(constraint(item: firstItem, attribute: .leading, toItem: topView))
+            constraints.append(constraint(item: firstItem, attribute: .trailing, toItem: bottomView))
+
+            if alignment == .center {
+                constraints.append(constraint(item: firstItem, attribute: .centerX, toItem: arrangedSubviews.first!))
+            }
+        }
+        
+        return constraints
+    }
+    
+    private func equalAttributes(views: [UIView], attribute: NSLayoutConstraint.Attribute, priority: Float = 1000) -> [NSLayoutConstraint] {
+        var currentPriority = priority
+        var constraints = [NSLayoutConstraint]()
+        if views.count > 0 {
+            
+            var firstView: UIView?
+
+            let countDownPriority = (currentPriority < 1000)
+            for view in views {
+                if let firstView = firstView {
+                    constraints.append(constraint(item: firstView, attribute: attribute, toItem: view, priority: currentPriority))
+                } else {
+                    firstView = view
+                }
+                if countDownPriority {
+                    currentPriority -= 1
+                }
+            }
+        }
+        return constraints
+    }
+
+    // Convenience method to help make NSLayoutConstraint in a less verbose way
+    private func constraint(item view1: AnyObject, attribute attr1: NSLayoutConstraint.Attribute, relatedBy relation: NSLayoutConstraint.Relation = .equal, toItem view2: AnyObject?, attribute attr2: NSLayoutConstraint.Attribute? = nil, multiplier: CGFloat = 1, constant c: CGFloat = 0, priority: Float = 1000) -> NSLayoutConstraint {
+
+        let attribute2 = attr2 != nil ? attr2! : attr1
+
+        let constraint = NSLayoutConstraint(item: view1, attribute: attr1, relatedBy: relation, toItem: view2, attribute: attribute2, multiplier: multiplier, constant: c)
+        constraint.priority = UILayoutPriority(rawValue: priority)
+        return constraint
+    }
+    
+    private func isHidden(_ view: UIView) -> Bool {
+        if view.isHidden {
+            return true
+        }
+        return animatingToHiddenViews.index(of: view) != nil
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackViewAlignment.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackViewAlignment.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackViewAlignment.swift	(working copy)
@@ -0,0 +1,19 @@
+//
+//  TZStackViewAlignment.swift
+//  TZStackView
+//
+//  Created by Tom van Zummeren on 15/06/15.
+//  Copyright © 2015 Tom van Zummeren. All rights reserved.
+//
+
+import Foundation
+
+@objc public enum TZStackViewAlignment: Int {
+    case fill
+    case center
+    case leading
+    case top
+    case trailing
+    case bottom
+    case firstBaseline
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackViewDistribution.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackViewDistribution.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TZStackView/TZStackViewDistribution.swift	(working copy)
@@ -0,0 +1,16 @@
+//
+//  TZStackViewDistribution.swift
+//  TZStackView
+//
+//  Created by Tom van Zummeren on 10/06/15.
+//  Copyright © 2015 Tom van Zummeren. All rights reserved.
+//
+import Foundation
+
+@objc public enum TZStackViewDistribution: Int {
+    case fill
+    case fillEqually
+    case fillProportionally
+    case equalSpacing
+    case equalCentering
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TransitionAnimations.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TransitionAnimations.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TransitionAnimations.swift	(working copy)
@@ -0,0 +1,177 @@
+//
+//  PopupDialogTransitionAnimations.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/*!
+ Presentation transition styles for the popup dialog
+
+ - BounceUp:   Dialog bounces in from bottom and is dismissed to bottom
+ - BounceDown: Dialog bounces in from top and is dismissed to top
+ - ZoomIn:     Dialog zooms in and is dismissed by zooming out
+ - FadeIn:     Dialog fades in and is dismissed by fading out
+ */
+@objc public enum PopupDialogTransitionStyle: Int {
+    case bounceUp
+    case bounceDown
+    case zoomIn
+    case fadeIn
+}
+
+/// Dialog bounces in from bottom and is dismissed to bottom
+final internal class BounceUpTransition: TransitionAnimator {
+
+    init(direction: AnimationDirection) {
+        super.init(inDuration: 0.22, outDuration: 0.2, direction: direction)
+    }
+
+    override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+        super.animateTransition(using: transitionContext)
+
+        switch direction {
+        case .in:
+            to.view.bounds.origin = CGPoint(x: 0, y: -from.view.bounds.size.height)
+            UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: {
+                self.to.view.bounds = self.from.view.bounds
+            }) { (completed) in
+                transitionContext.completeTransition(completed)
+            }
+        case .out:
+            UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: {
+                self.from.view.bounds.origin = CGPoint(x: 0, y: -self.from.view.bounds.size.height)
+                self.from.view.alpha = 0.0
+            }) { (completed) in
+                transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
+            }
+        }
+    }
+}
+
+
+/// Dialog bounces in from top and is dismissed to top
+final internal class BounceDownTransition: TransitionAnimator {
+
+    init(direction: AnimationDirection) {
+        super.init(inDuration: 0.22, outDuration: 0.2, direction: direction)
+    }
+
+    override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+        super.animateTransition(using: transitionContext)
+
+        switch direction {
+        case .in:
+            to.view.bounds.origin = CGPoint(x: 0, y: from.view.bounds.size.height)
+            UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: {
+                self.to.view.bounds = self.from.view.bounds
+            }) { (completed) in
+                transitionContext.completeTransition(completed)
+            }
+        case .out:
+            UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: {
+                self.from.view.bounds.origin = CGPoint(x: 0, y: self.from.view.bounds.size.height)
+                self.from.view.alpha = 0.0
+            }) { (completed) in
+                transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
+            }
+        }
+    }
+}
+
+/// Dialog zooms in and is dismissed by zooming out
+final internal class ZoomTransition: TransitionAnimator {
+
+    init(direction: AnimationDirection) {
+        super.init(inDuration: 0.22, outDuration: 0.2, direction: direction)
+    }
+
+    override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+        super.animateTransition(using: transitionContext)
+
+        switch direction {
+        case .in:
+            to.view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
+            UIView.animate(withDuration: 0.6, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0, options: [.curveEaseOut], animations: {
+                self.to.view.transform = CGAffineTransform(scaleX: 1, y: 1)
+            }) { (completed) in
+                transitionContext.completeTransition(completed)
+            }
+        case .out:
+            UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: {
+                self.from.view.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
+                self.from.view.alpha = 0.0
+            }) { (completed) in
+                transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
+            }
+        }
+    }
+}
+
+/// Dialog fades in and is dismissed by fading out
+final internal class FadeTransition: TransitionAnimator {
+
+    init(direction: AnimationDirection) {
+        super.init(inDuration: 0.22, outDuration: 0.2, direction: direction)
+    }
+
+    override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+        super.animateTransition(using: transitionContext)
+
+        switch direction {
+        case .in:
+            to.view.alpha = 0
+            UIView.animate(withDuration: 0.6, delay: 0.0, options: [.curveEaseOut],
+            animations: {
+                self.to.view.alpha = 1
+            }) { (completed) in
+                transitionContext.completeTransition(completed)
+            }
+        case .out:
+            UIView.animate(withDuration: outDuration, delay: 0.0, options: [.curveEaseIn], animations: {
+                self.from.view.alpha = 0.0
+            }) { (completed) in
+                transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
+            }
+        }
+    }
+}
+
+/// Used for the always drop out animation with pan gesture dismissal
+final internal class DismissInteractiveTransition: TransitionAnimator {
+
+    init() {
+        super.init(inDuration: 0.22, outDuration: 0.32, direction: .out)
+    }
+
+    override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+        super.animateTransition(using: transitionContext)
+        UIView.animate(withDuration: outDuration, delay: 0.0, options: [.beginFromCurrentState], animations: {
+            self.from.view.bounds.origin = CGPoint(x: 0, y: -self.from.view.bounds.size.height)
+            self.from.view.alpha = 0.0
+        }) { (completed) in
+            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
+        }
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TransitionAnimator.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TransitionAnimator.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/TransitionAnimator.swift	(working copy)
@@ -0,0 +1,61 @@
+//
+//  PopupDialogTransitionAnimator.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/// Base class for custom transition animations
+internal class TransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
+
+    var to: UIViewController!
+    var from: UIViewController!
+    let inDuration: TimeInterval
+    let outDuration: TimeInterval
+    let direction: AnimationDirection
+
+    init(inDuration: TimeInterval, outDuration: TimeInterval, direction: AnimationDirection) {
+        self.inDuration = inDuration
+        self.outDuration = outDuration
+        self.direction = direction
+        super.init()
+    }
+
+    internal func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
+        return direction == .in ? inDuration : outDuration
+    }
+
+    internal func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
+        switch direction {
+        case .in:
+            to = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
+            from = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
+            let container = transitionContext.containerView
+            container.addSubview(to.view)
+        case .out:
+            to = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
+            from = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
+        }
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIImageView+Calculations.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIImageView+Calculations.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIImageView+Calculations.swift	(working copy)
@@ -0,0 +1,44 @@
+//
+//  UIImageView+Calculations.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+internal extension UIImageView {
+
+    /*!
+     Calculates the height of the the UIImageView has to
+     have so the image is displayed correctly
+     - returns: Height to set on the imageView
+     */
+    internal func pv_heightForImageView() -> CGFloat {
+        guard let image = image, image.size.height > 0 else {
+            return 0.0
+        }
+        let width = bounds.size.width
+        let ratio = image.size.height / image.size.width
+        return width * ratio
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIView+Animations.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIView+Animations.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIView+Animations.swift	(working copy)
@@ -0,0 +1,65 @@
+//
+//  UIView+Animations.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+/*!
+ The intended direction of the animation
+ - in:  Animate in
+ - out: Animate out
+ */
+internal enum AnimationDirection {
+    case `in`
+    case out
+}
+
+internal extension UIView {
+
+    /// The key for the fade animation
+    internal var fadeKey: String { return "FadeAnimation" }
+
+    /*!
+     Applies a fade animation to this view
+     - parameter direction: Animation direction
+     - parameter value:     The end value of this animation
+     - parameter duration:  The duration of this animation
+     */
+    internal func pv_fade(_ direction: AnimationDirection, _ value: Float, duration: CFTimeInterval = 0.08) {
+        layer.removeAnimation(forKey: fadeKey)
+        let animation = CABasicAnimation(keyPath: "opacity")
+        animation.duration = duration
+        animation.fromValue = layer.presentation()?.opacity
+        layer.opacity = value
+        animation.fillMode = CAMediaTimingFillMode.forwards
+        layer.add(animation, forKey: fadeKey)
+    }
+
+    internal func pv_layoutIfNeededAnimated(duration: CFTimeInterval = 0.08) {
+        UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(), animations: {
+            self.layoutIfNeeded()
+        }, completion: nil)
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIViewController+Visibility.swift
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIViewController+Visibility.swift	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/PopupDialog/Classes/UIViewController+Visibility.swift	(working copy)
@@ -0,0 +1,52 @@
+//
+//  UIViewController+Visibility.swift
+//
+//  Copyright (c) 2016 Orderella Ltd. (http://orderella.co.uk)
+//  Author - Martin Wildfeuer (http://www.mwfire.de)
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+//
+
+import Foundation
+import UIKit
+
+// http://stackoverflow.com/questions/2777438/how-to-tell-if-uiviewcontrollers-view-is-visible
+internal extension UIViewController {
+
+    internal var isTopAndVisible: Bool {
+        return isVisible && isTopViewController
+    }
+
+    internal var isVisible: Bool {
+        if isViewLoaded {
+            return view.window != nil
+        }
+        return false
+    }
+
+    internal var isTopViewController: Bool {
+        if self.navigationController != nil {
+            return self.navigationController?.visibleViewController === self
+        } else if self.tabBarController != nil {
+            return self.tabBarController?.selectedViewController == self && self.presentedViewController == nil
+        } else {
+            return self.presentedViewController == nil && self.isVisible
+        }
+    }
+}
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ShareViewController.h
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ShareViewController.h	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ShareViewController.h	(working copy)
@@ -0,0 +1,14 @@
+//
+//  ShareViewController.h
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import <Social/Social.h>
+
+@interface ShareViewController : SLComposeServiceViewController
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ShareViewController.m
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ShareViewController.m	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ShareViewController.m	(working copy)
@@ -0,0 +1,34 @@
+//
+//  ShareViewController.m
+//  ImportFile
+//
+//  Created by wangxy on 2019/8/22.
+//  Copyright © 2019 wangxy. All rights reserved.
+//
+
+#import "ShareViewController.h"
+
+@interface ShareViewController ()
+
+@end
+
+@implementation ShareViewController
+
+- (BOOL)isContentValid {
+    // Do validation of contentText and/or NSExtensionContext attachments here
+    return YES;
+}
+
+- (void)didSelectPost {
+    // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
+    
+    // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
+    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
+}
+
+- (NSArray *)configurationItems {
+    // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
+    return @[];
+}
+
+@end
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/en.lproj/Localizable.strings
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/en.lproj/Localizable.strings	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/en.lproj/Localizable.strings	(working copy)
@@ -0,0 +1,7 @@
+/* 
+  Localizable.strings
+  MacTunnel
+
+  Created by wangxy on 2019/8/29.
+  Copyright © 2019 wangxy. All rights reserved.
+*/
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ja.lproj/Localizable.strings
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ja.lproj/Localizable.strings	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ja.lproj/Localizable.strings	(working copy)
@@ -0,0 +1,11 @@
+/* 
+  Localizable.strings
+  MacTunnel
+
+  Created by wangxy on 2019/8/29.
+  Copyright © 2019 wangxy. All rights reserved.
+*/
+"Are you sure to import this certificate file?" = "この証明書をインポートしてもよろしいですか?";
+"Fail to import this file." = "ファイルのインポートに失敗しました。";
+"OK" = "OK";
+"Cancel" = "キャンセル";
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/ja.lproj/MainInterface.strings
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/ja.lproj/MainInterface.strings	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/ja.lproj/MainInterface.strings	(working copy)
@@ -0,0 +1 @@
+
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hans.lproj/Localizable.strings
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hans.lproj/Localizable.strings	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hans.lproj/Localizable.strings	(working copy)
@@ -0,0 +1,12 @@
+/* 
+  Localizable.strings
+  MacTunnel
+
+  Created by wangxy on 2019/8/29.
+  Copyright © 2019 wangxy. All rights reserved.
+*/
+
+"Are you sure to import this certificate file?" = "确认导入此证书吗？";
+"Fail to import this file." = "无法导入该文件。";
+"OK" = "好";
+"Cancel" = "取消";
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hans.lproj/MainInterface.strings
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hans.lproj/MainInterface.strings	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hans.lproj/MainInterface.strings	(working copy)
@@ -0,0 +1 @@
+
Index: /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hant.lproj/MainInterface.strings
===================================================================
--- /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hant.lproj/MainInterface.strings	(nonexistent)
+++ /branches/ag_client_motionProGlobal_ios_new/ImportFile/zh-Hant.lproj/MainInterface.strings	(working copy)
@@ -0,0 +1 @@
+
