Service class for managing multiple domains within Google Apps.
Inheritance: Google.GData.Apps.AppsPropertyService
        /// <summary>
        /// This console application demonstrates all the Google Apps
        /// MultiDomain Management APIs. 
        /// </summary>
        /// <param name="args">Command-line arguments: args[0] is
        /// the primary domain, args[1] is the secondary domain,
        /// args[2] is the admin email address, args[3] is the admin 
        /// password and args[4] is test user(email address)
        /// 
        /// Example: AppsMultiDomainDemo example.com alias.com [email protected] my_password test_user_email</param>
        public static void Main(string[] args)
        {
            if (args.Length != 5)
            {
                Console.WriteLine("Syntax: AppsMultiDomainDemo <primary_domain> <secondary_domain> <admin_email> <admin_password> <testUserEmail>");
            }
            else
            {
                primaryDomain = args[0];
                secondaryDomain = args[1];
                adminEmail = args[2];
                adminPassword = args[3];
                testUserEmail = args[4];

                MultiDomainManagementService service = new MultiDomainManagementService(primaryDomain, "multidomainapis-apps-demo");
                service.setUserCredentials(adminEmail, adminPassword);

                RunSample(service);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="service"></param>
        private static void RunSample(MultiDomainManagementService service)
        {
            const String testUserHashFunction = "SHA-1";
            const String testUserPassword = "******";
            const String testUserFirstName = "Liz";
            const String testUserLastName = "Smith";
            const bool testUserIsAdmin = true;
            const String testUserNewFirstName = "Elizabeth";
            String testUserNewEmail = "liz@" + secondaryDomain;
            String testUserAliasEmail = "helpdesk@" + secondaryDomain;

            try
            {
                // Create a new Domain User
                Console.WriteLine("\n-----------Creating domain user-----------");
                AppsExtendedEntry entry = service.CreateDomainUser(primaryDomain, testUserEmail, testUserPassword,
                    testUserHashFunction, testUserFirstName, testUserLastName, testUserIsAdmin);
                Console.WriteLine("Created: " +
                                  entry.getPropertyValueByName(AppsMultiDomainNameTable.UserEmail));

                // Update Domain User and list all properties
                Console.WriteLine("\n-----------Updating domain user----");
                IDictionary<MultiDomainManagementService.MultiDomainUserProperty, string> updates =
                    new Dictionary<MultiDomainManagementService.MultiDomainUserProperty, string>();
                updates[MultiDomainManagementService.MultiDomainUserProperty.FirstName] = testUserNewFirstName;
                entry = service.UpdateDomainUser(primaryDomain, testUserEmail, updates);
                foreach (PropertyElement element in entry.Properties)
                {
                    Console.WriteLine(String.Format("{0} - {1}", element.Name, element.Value));
                }

                // Create a new Domain User to be renamed
                Console.WriteLine("\n-----------Creating domain user to be renamed-----------");
                String tempEmail = "TOBERENAMED@" + primaryDomain;
                entry = service.CreateDomainUser(primaryDomain, tempEmail, testUserPassword,
                                                 testUserFirstName, testUserLastName, testUserIsAdmin);
                Console.WriteLine("Created: " +
                                  entry.getPropertyValueByName(AppsMultiDomainNameTable.UserEmail));

                // Rename Domain User
                Console.WriteLine("\n-----------Renaming domain user---------------------");
                entry = service.RenameDomainUser(primaryDomain, tempEmail, testUserNewEmail);
                Console.WriteLine("Renamed domain user: "******"\n-----------Retrieving domain user----");
                entry = service.RetrieveDomainUser(primaryDomain, testUserEmail);
                String firstName =
                    entry.getPropertyValueByName(AppsMultiDomainNameTable.FirstName);
                Console.WriteLine("FirstName: " + firstName);

                // Retrieve all domain users unit and list the emails
                Console.WriteLine("\n-----------Retrieving all domain users----");
                AppsExtendedFeed feed = service.RetrieveAllDomainUsers(primaryDomain);
                foreach (AppsExtendedEntry unit in feed.Entries)
                {
                    Console.WriteLine(
                        unit.getPropertyValueByName(AppsMultiDomainNameTable.UserEmail));
                }

                // Create a new User Alias
                Console.WriteLine("\n-----------Creating user alias-----------");
                entry = service.CreateDomainUserAlias(primaryDomain, testUserEmail, testUserAliasEmail);
                Console.WriteLine("Created Alias: " +
                                  entry.getPropertyValueByName(AppsMultiDomainNameTable.AliasEmail));

                // Retrieve User Alias
                entry = service.RetrieveDomainUserAlias(primaryDomain, testUserAliasEmail);
                String userEmail =
                    entry.getPropertyValueByName(AppsMultiDomainNameTable.UserEmail);
                Console.WriteLine("UserEmail: " + userEmail);

                // Retrieve all user aliases for the domain
                Console.WriteLine("\n-----------Retrieving all user aliases----");
                feed = service.RetrieveAllDomainUserAlias(primaryDomain);
                foreach (AppsExtendedEntry unit in feed.Entries)
                {
                    Console.WriteLine(
                        unit.getPropertyValueByName(AppsMultiDomainNameTable.UserEmail));
                }

                // Retrieve all aliases for an user
                Console.WriteLine("\n-----------Retrieving all aliases for user----");
                feed = service.RetrieveAllDomainUserAliasForUser(primaryDomain, testUserEmail);
                foreach (AppsExtendedEntry unit in feed.Entries)
                {
                    Console.WriteLine(
                        unit.getPropertyValueByName(AppsMultiDomainNameTable.AliasEmail));
                }

                // Delete User Alias
                Console.WriteLine("\n-----------Deleting alias----");
                service.DeleteDomainUserAlias(primaryDomain, testUserAliasEmail);

                // Delete User
                Console.WriteLine("\n-----------Deleting user----");
                service.DeleteDomainUser(primaryDomain, testUserEmail);
            }
            catch (AppsException a)
            {
                Console.WriteLine("A Google Apps error occurred.");
                Console.WriteLine();
                Console.WriteLine("Error code: {0}", a.ErrorCode);
                Console.WriteLine("Invalid input: {0}", a.InvalidInput);
                Console.WriteLine("Reason: {0}", a.Reason);
            }
        }
        static void Main( string[] args )
        {
            //parse options
            var options = GoogleAppsAddDomainAliasProgramOptions.Parse( args );
            if( options.Help ) { options.PrintHelp( Console.Out ); return; }
            if( options.Incomplete ) { CollectOptionsInteractiveConsole( options ); }
            if( !options.Username.Contains( "@" ) )
            {
                Console.WriteLine( "Whoops. Your username must be an email address." );
                options.Username = null;
                CollectOptionsInteractiveConsole( options );
            }
            //create service object
            var service = new MultiDomainManagementService( options.Domain, null );
            service.setUserCredentials( options.Username, options.Password );

            try
            {
                //add aliases
                if( string.IsNullOrEmpty( options.File ) ) { AddAliasInteractiveConsole( service, options.Domain ); }
                else { AddAliasBatch( Console.Out, service, options.Domain, options.File ); }
            }
            catch( InvalidCredentialsException )
            {
                Console.WriteLine();
                Console.WriteLine( "Invalid Credentials." );
            }
            catch( CaptchaRequiredException )
            {
                Console.WriteLine();
                Console.WriteLine( "Your account has been locked by Google." );
                Console.WriteLine( "Use your browser to unlock your account." );
                Console.WriteLine( "https://www.google.com/accounts/UnlockCaptcha" );
            }
        }
        static void AddAliasInteractiveConsole( MultiDomainManagementService service, string primaryDomain )
        {
            Console.WriteLine();
            Console.WriteLine( "No batch file option (-f). Entering interactive mode." );
            Console.WriteLine( "Press CTRL+C to quit." );
            Console.WriteLine();
            while( true ) //continue until CTRL+C
            {
                bool confirm = false;
                string user=null, alias=null;
                while( string.IsNullOrEmpty( user ) )
                {
                    Console.Write( "User to alias [user@domain]: " );
                    user = Console.ReadLine();
                }
                while( string.IsNullOrEmpty( alias ) )
                {
                    Console.Write( String.Format( "Alias for {0}: ", user ) );
                    alias = Console.ReadLine();
                }

                Console.Write( string.Format("Please confirm: Add alias {0} to {1} (y/n)? ", alias, user) );
                confirm = Console.ReadLine().StartsWith( "y", StringComparison.InvariantCultureIgnoreCase );
                if( !confirm )
                {
                    Console.WriteLine( "Cancelled. Alias not created.");
                }
                else
                {
                    try
                    {
                        Console.WriteLine( AddAlias( service, primaryDomain, user, alias ) );
                    }
                    catch( InvalidCredentialsException )
                    {
                        Console.WriteLine();
                        Console.WriteLine( "Invalid Credentials." );
                        Console.WriteLine();
                        //collect new credentials
                        var options = new GoogleAppsAddDomainAliasProgramOptions() { Domain = primaryDomain };
                        CollectOptionsInteractiveConsole( options );
                        service.setUserCredentials( options.Username, options.Password );
                    }
                }
                Console.WriteLine();
            }
        }
        static void AddAliasBatch( TextWriter textWriter, MultiDomainManagementService service, string primaryDomain, string file )
        {
            try
            {
                using( var stream = File.OpenRead( file ) )
                using( var reader = new StreamReader( stream ) )
                {
                    string line;
                    long position=0;
                    while( null != (line = reader.ReadLine()) )
                    {
                        position++;
                        line = line.Trim();
                        if( line.Length == 0 || line.StartsWith( "#" ) ) { continue; } //ignore lines that start with '#'

                        string response;
                        var split = line.Split('\t');
                        if( split.Length != 2 )
                        {
                            response = string.Format( "Line {0}: Error row not in the expected format.", position );
                        }
                        else
                        {
                            string user = split[0];
                            string alias = split[1];
                            string result = AddAlias( service, primaryDomain, user, alias );
                            response = string.Format( "Line {0}: {1}", position, result );
                        }
                        textWriter.WriteLine( response );
                    }
                }

            }
            catch( IOException ex )
            {
                textWriter.WriteLine();
                textWriter.WriteLine( ex.Message );
            }
        }
 static string AddAlias( MultiDomainManagementService service, string primaryDomain, string user, string alias )
 {
     try
     {
         var entry = service.CreateDomainUserAlias( primaryDomain, user, alias );
         return string.Format(
             "Alias {0} created for {1}.",
             entry.getPropertyValueByName( AppsMultiDomainNameTable.AliasEmail ),
             user ); //return alias from server
     }
     catch( GDataRequestException ex )
     {
         return string.Format( "Error creating alias: {0}.", ex.ParseError() ); //or else return error message
     }
 }