def build_model_code(client):
    """
    Generate source code for e-conomic models based on WSDL connection.
    This is based on the assumption that the API follows a specific method naming-convention.
    Not all models and attributes has been tested.
    The source-generation is mostly to help improve readability and IDE auto-completion.

    :param client:
    :return: source code for models.py
    """
    models = {}
    references = {}
    for method in client.wsdl.services[0].ports[0].methods.values():
        if not '_' in method.name:
            continue
        model, action = method.name.split('_')
        models.setdefault(model, {'properties': [], 'filters': []})
        references[model] = model
        if model[-1] == 'y':
            references[model[:-1] + 'ies'] = model
        else:
            references[model+'s'] = model

    references['OurReference'] = 'Employee'
    references['GetYourReference'] = 'DebtorContact'
    references['GetAttention'] = 'DebtorContact'
    references['Layout'] = 'TemplateCollection'
    special = {
        'Order_GetPdf': {
            'type': 'EConomicsFileProperty',
            'args': ["'Order_GetPdf'", "'pdf'"]
        },
        'Invoice_GetPdf': {
            'type': 'EConomicsFileProperty',
            'args': ["'Invoice_GetPdf'", "'pdf'"]
        },
        'CurrentInvoice_GetPdf': {
            'type': 'EConomicsFileProperty',
            'args': ["'CurrentInvoice_GetPdf'", "'pdf'"]
        }
    }
    for line in ['Order', 'Invoice', 'CurrentInvoice', 'Quotation']:
        method = '%s_GetLines' % line
        special[method] = {
            'type': 'EConomicsReferenceList',
            'args': ["'%sLine'" % line, "'%s'" % method]
        }

    for method in client.wsdl.services[0].ports[0].methods.values():
        if not '_' in method.name:
            continue
        model, action = method.name.split('_')
        if action in ['GetData', 'GetAll', 'GetDataArray']:
            continue
        modeldata = models[model]

        if action == 'GetAllUpdated':
            camelname = action[3:]
            modeldata['filters'].append({'name': pythonize(camelname), 'method': action})
        if re.findall('GetAll[A-Z].+', action):
            camelname = action[3:]
            modeldata['filters'].append({'name': pythonize(camelname), 'method': action})
        elif action.startswith('FindBy'):
            camelname = action[6:]
            modeldata['filters'].append({'name': pythonize(camelname), 'method': action})

        elif action.startswith('Get'):
            propname = action[3:]
            pyname = pythonize(propname)
            if not propname:
                continue
            get_type = re.findall('Get(%s)[a-z0-9]*?$' % ('|'.join(references.keys())), action)
            if get_type and get_type[0] in references:
                refmodel = references[get_type[0]]
                if action[-1] == 's':
                    modeldata['properties'].append({
                        'type': 'EConomicsReferenceList',
                        'args': ["'%s'" % propname, "'%s'" % refmodel,  "'%s'" % method.name],
                        'name': pyname
                    })
                else:
                    modeldata['properties'].append({
                        'type': 'EConomicsReference',
                        'args': ["'%s'" % propname, "'%s'" % refmodel],
                        'name': pyname
                    })
            elif method.name in special:
                spdata = special[method.name]
                modeldata['properties'].append({
                    'type': spdata['type'],
                    'args': ["'%s'" % propname] + spdata['args'],
                    'name': pyname
                })
            else:
                modeldata['properties'].append({
                    'type': 'EConomicsProperty',
                    'args': ["'%s'" % propname],
                    'name': pyname
                })

    classes = []
    for modelname, modeldata in models.items():

        propertycode = ["%s = %s(%s)" % (md['name'], md['type'], ', '.join(md['args']))
                        for md in modeldata['properties']]
        code = "class %s(%s):\n    __filters__ = %r\n    %s" % (modelname, 'EConomicsModel',
                                                                modeldata['filters'], '\n    '.join(propertycode))
        classes.append(code)
    return "from pyconomic.base import *\n\n\n" + "\n\n\n".join(classes)