a method for creating a bucket on AWS S3
            
        :param bucket_name: string with name of bucket
        :param access_control: string with type of access control policy
        :param version_control: [optional] boolean to enable versioning of records
        :param log_destination: [optional] dictionary with bucket name and prefix of log bucket
        :param lifecycle_rules: [optional] list of dictionaries with rules for aging data
        :param tag_list: [optional] list of dictionaries with key and value for tag
        :param notification_settings: [optional] list of dictionaries with notification details
        :param region_replication: [optional] dictionary with replication settings (WIP)
        :param access_policy: [optional] dictionary with policy for user access (WIP)
        :return: string with name of bucket

def create_bucket(self, bucket_name, access_control='private', version_control=False, log_destination=None, lifecycle_rules=None, tag_list=None, notification_settings=None,  region_replication=None, access_policy=None):

        '''
            a method for creating a bucket on AWS S3
            
        :param bucket_name: string with name of bucket
        :param access_control: string with type of access control policy
        :param version_control: [optional] boolean to enable versioning of records
        :param log_destination: [optional] dictionary with bucket name and prefix of log bucket
        :param lifecycle_rules: [optional] list of dictionaries with rules for aging data
        :param tag_list: [optional] list of dictionaries with key and value for tag
        :param notification_settings: [optional] list of dictionaries with notification details
        :param region_replication: [optional] dictionary with replication settings (WIP)
        :param access_policy: [optional] dictionary with policy for user access (WIP)
        :return: string with name of bucket
        '''

        title = '%s.create_bucket' % self.__class__.__name__
        
    # validate inputs
        input_fields = {
            'bucket_name': bucket_name,
            'access_control': access_control,
            'log_destination': log_destination,
            'lifecycle_rules': lifecycle_rules,
            'tag_list': tag_list,
            'notification_settings': notification_settings,
            'region_replication': region_replication,
            'access_policy': access_policy
        }
        for key, value in input_fields.items():
            if value:
                object_title = '%s(%s=%s)' % (title, key, str(value))
                self.fields.validate(value, '.%s' % key, object_title)

    # verify requirements and limits
        self.list_buckets()
        if bucket_name in self.bucket_list:
            raise ValueError('S3 Bucket "%s" already exists in aws region %s.' % (bucket_name, self.iam.region_name))
        max_buckets = self.fields.metadata['limits']['max_buckets_per_account']
        if len(self.bucket_list) >= max_buckets:
            raise Exception('S3 account %s already at maximum %s buckets.' % (self.iam.owner_id, max_buckets))
        if log_destination:
            log_name = log_destination['name']
            if not log_name in self.bucket_list:
                if log_name != bucket_name:
                    raise ValueError('S3 Bucket "%s" for logging does not exist in aws region %s.' % (log_name, self.iam.region_name))
            else:
                log_details = self.read_bucket(log_name)
                if log_details['access_control'] != 'log-delivery-write':
                    raise ValueError('S3 Bucket "%s" for logging does not have "log-delivery-write" access control.' % log_name)
            if not 'prefix' in log_destination.keys():
                log_destination['prefix'] = ''

    # TODO: check to see if required notification arns exist
        if notification_settings:
            for notification in notification_settings:
                arn_id = notification['arn']

    # create key word arguments dictionary
        kw_args = {
            'Bucket': bucket_name,
            'ACL': access_control
        }
        if self.iam.region_name != 'us-east-1':
            kw_args['CreateBucketConfiguration'] = { 'LocationConstraint': self.iam.region_name }

    # send request to s3
        self.iam.printer('Creating bucket "%s".' % bucket_name, flush=True)
        try:
            response = self.connection.create_bucket(**kw_args)
            self.iam.printer('.', flush=True)
        except:
            raise AWSConnectionError(title)

    # if true, activate version_control attribute
        if version_control:
            try:
                self.connection.put_bucket_versioning(
                    Bucket=bucket_name,
                    VersioningConfiguration={ 'Status': 'Enabled' }
                )
                self.iam.printer('.', flush=True)
            except:
                raise AWSConnectionError(title)

    # if present, direct bucket logging to bucket location
        if log_destination:
            try:
                kw_args = {
                    'Bucket': bucket_name,
                    'BucketLoggingStatus': {
                        'LoggingEnabled': {
                            'TargetBucket': log_destination['name']
                        }
                    }
                }
                if log_destination['prefix']:
                    kw_args['BucketLoggingStatus']['LoggingEnabled']['TargetPrefix'] = log_destination['prefix']
                self.connection.put_bucket_logging(**kw_args)
                self.iam.printer('.', flush=True)
            except:
                raise AWSConnectionError(title)

    # if present, assign lifecycle rules
        if lifecycle_rules:
            kw_args = {
                'Bucket': bucket_name,
                'LifecycleConfiguration': { 'Rules': [ ] }
            }
            for rule in lifecycle_rules:
                details = {
                    'Prefix': rule['prefix'],
                    'Status': 'Enabled'
                }
                if rule['action'] == 'archive':
                    if rule['current_version']:
                        details['Transition'] = {
                            'Days': rule['longevity'],
                            'StorageClass': 'GLACIER'
                        }
                    else:
                        details['NoncurrentVersionTransition'] = {
                            'NoncurrentDays': rule['longevity'],
                            'StorageClass': 'GLACIER'
                        }
                else:
                    if rule['current_version']:
                        details['Expiration'] = { 'Days': rule['longevity'] }
                    else:
                        details['NoncurrentVersionExpiration'] = { 'NoncurrentDays': rule['longevity'] }
                kw_args['LifecycleConfiguration']['Rules'].append(details)
            try:
                response = self.connection.put_bucket_lifecycle(**kw_args)
                self.iam.printer('.', flush=True)
            except:
                raise AWSConnectionError(title)

    # if present, assign tags to bucket
        if tag_list:
            try:
                self.connection.put_bucket_tagging(
                    Bucket=bucket_name,
                    Tagging={ 'TagSet': self.iam.prepare(tag_list) }
                )
                self.iam.printer('.', flush=True)
            except:
                raise AWSConnectionError(title)

    # if present, assign notification rules
        if notification_settings:
            kw_args = {
                'Bucket': bucket_name,
                'NotificationConfiguration': {}
            }
            for notification in notification_settings:
                details = {
                    'Events': [],
                    'Filter': { 'Key': { 'FilterRules': [] } }
                }
                details['Events'].append(notification['event'])
                if notification['filters']:
                    for key, value in notification['filters'].items():
                        filter_details = {
                            'Name': key,
                            'Value': value
                        }
                        details['Filter']['Key']['FilterRules'].append(filter_details)
                if notification['service'] == 'sns':
                    details['TopicArn'] = notification['arn']
                    if not 'TopicConfigurations' in kw_args['NotificationConfiguration']:
                        kw_args['NotificationConfiguration']['TopicConfigurations'] = []
                    kw_args['NotificationConfiguration']['TopicConfigurations'].append(details)
                elif notification['service'] == 'sqs':
                    details['QueueArn'] = notification['arn']
                    if not 'QueueConfigurations' in kw_args['NotificationConfiguration']:
                        kw_args['NotificationConfiguration']['QueueConfigurations'] = []
                    kw_args['NotificationConfiguration']['QueueConfigurations'].append(details)
                elif notification['service'] == 'lambda':
                    if not 'LambdaFunctionConfigurations' in kw_args['NotificationConfiguration']:
                        kw_args['NotificationConfiguration']['LambdaFunctionConfigurations'] = []
                    details['LambdaFunctionArn'] = notification['arn']
                    kw_args['NotificationConfiguration']['LambdaFunctionConfigurations'].append(details)

            try:
                response = self.connection.put_bucket_notification_configuration(**kw_args)
                self.iam.printer('.', flush=True)
            except:
                raise AWSConnectionError(title)

     # TODO: if present, assign region replication
        if region_replication:
            try:
                # response = self.connection.put_bucket_replication(
                #     Bucket='string',
                #     ReplicationConfiguration={
                #         'Role': 'string',
                #         'Rules': [
                #             {
                #                 'ID': 'string',
                #                 'Prefix': 'string',
                #                 'Status': 'Enabled',
                #                 'Destination': {
                #                     'Bucket': 'string'
                #                 }
                #             },
                #         ]
                #     }
                # )
                self.iam.printer('.', flush=True)
            except:
                raise AWSConnectionError(title)

    # TODO: if present, assign access policy
        if access_policy:
            try:
                # response = self.connection.put_bucket_policy(
                #     Bucket='string',
                #     Policy='string'
                # )
                self.iam.printer('.', flush=True)
            except:
                raise AWSConnectionError(title)

        self.bucket_list.append(bucket_name)
        self.iam.printer(' done.')
        
        return bucket_name