/*
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at
 
 http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */

#import "CMISBrowserUtil.h"
#import "CMISConstants.h"
#import "CMISBrowserConstants.h"
#import "CMISRepositoryInfo.h"
#import "CMISPropertyDefinition.h"
#import "CMISRenditionData.h"
#import "CMISDocumentTypeDefinition.h"
#import "CMISFolderTypeDefinition.h"
#import "CMISRelationshipTypeDefinition.h"
#import "CMISItemTypeDefinition.h"
#import "CMISSecondaryTypeDefinition.h"
#import "CMISErrors.h"
#import "CMISDictionaryUtil.h"
#import "CMISRepositoryCapabilities.h"
#import "CMISObjectConverter.h"
#import "CMISAcl.h"
#import "CMISAce.h"
#import "CMISPrincipal.h"
#import "CMISAllowableActions.h"

NSString * const kCMISBrowserMinValueJSONProperty = @"\"minValue\":0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049,";
NSString * const kCMISBrowserMaxValueJSONProperty = @"\"maxValue\":179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,";

@interface NSObject (CMISUtil)

+ (void)performBlock:(void (^)(void))block;

@end

@implementation NSObject (CMISUtil)

+ (void)performBlock:(void (^)(void))block
{
    [NSObject performSelector:@selector(executeBlock:) onThread:[NSThread currentThread] withObject:block waitUntilDone:NO];
}

+ (void)executeBlock:(void (^)(void))block {
    block();
}

@end

@implementation CMISBrowserUtil

+ (NSDictionary *)repositoryInfoDictionaryFromJSONData:(NSData *)jsonData bindingSession:(CMISBindingSession *)bindingSession error:(NSError **)outError
{
    // TODO: error handling i.e. if jsonData is nil, also handle outError being nil
    
    // parse the JSON response
    NSError *serialisationError = nil;
    id jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&serialisationError];
    
    NSMutableDictionary *repositories = nil;
    if (!serialisationError) {
        repositories = [NSMutableDictionary dictionary];
        
        // parse the json into CMISRepositoryInfo objects and store in self.repositories
        NSArray *repos = [jsonDictionary allValues];
        for (NSDictionary *repo in repos) {
            CMISRepositoryInfo *repoInfo = [CMISRepositoryInfo new];
            repoInfo.identifier = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryId];
            repoInfo.name = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryName];
            repoInfo.summary = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryDescription];
            repoInfo.vendorName = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONVendorName];
            repoInfo.productName = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONProductName];
            repoInfo.productVersion = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONProductVersion];
            repoInfo.rootFolderId = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRootFolderId];
            NSString *repositoryUrl = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRepositoryUrl];
            NSString *rootFolderUrl = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONRootFolderUrl];
            
            repoInfo.repositoryCapabilities = [CMISBrowserUtil convertRepositoryCapabilities:[repo cmis_objectForKeyNotNull:kCMISBrowserJSONCapabilities]];
            //TOOD aclCapabilities
            repoInfo.latestChangeLogToken = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONLatestChangeLogToken];
            
            repoInfo.cmisVersionSupported = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONCMISVersionSupported];
            repoInfo.thinClientUri = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONThinClientUri];

            //TODO repoInfo.changesIncomplete = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONChangesIncomplete);
            //TODO changesOnType

            repoInfo.principalIdAnonymous = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONPrincipalIdAnonymous];
            repoInfo.principalIdAnyone = [repo cmis_objectForKeyNotNull:kCMISBrowserJSONPrincipalIdAnyone];
            
            //handle extensions
            repoInfo.extensions = [CMISObjectConverter convertExtensions:repo cmisKeys:[CMISBrowserConstants repositoryInfoKeys]];
            
            // store the repo and root folder URLs in the session (when the repoId matches)
            if ([repoInfo.identifier isEqualToString:bindingSession.repositoryId]) {
                [bindingSession setObject:rootFolderUrl forKey:kCMISBrowserBindingSessionKeyRootFolderUrl];
                [bindingSession setObject:repositoryUrl forKey:kCMISBrowserBindingSessionKeyRepositoryUrl];
            }
            
            [repositories setObject:repoInfo forKey:repoInfo.identifier];
        }
    } else {
        if (outError != NULL) *outError = [CMISErrors cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime];
        return nil;
    }

    return repositories;
}

+ (CMISTypeDefinition *)typeDefinitionFromJSONData:(NSData *)jsonData error:(NSError **)outError
{
    // TODO: error handling i.e. if jsonData is nil, also handle outError being nil
    
    // parse the JSON response
    NSError *serialisationError = nil;
    id jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&serialisationError];
    
    // HACK: An Apple bug can cause deserialisation to fail if very small or very large numbers are used.
    // This is usually caused when the web service providing the JSON has used a MIN or MAX value for the data type.
    // If an error occurred attempt to remove the offending data and re-try the deserialisation.
    if (serialisationError)
    {
        // convert to string
        NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        
        // remove the minValue and maxValue properties as they are effectively indicating any reasonable value is valid
        jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMinValueJSONProperty withString:@""];
        jsonString = [jsonString stringByReplacingOccurrencesOfString:kCMISBrowserMaxValueJSONProperty withString:@""];
        
        // re-try and JSON parse
        serialisationError = nil;
        jsonDictionary = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&serialisationError];
    }
    
    CMISTypeDefinition *typeDef = nil;
    if (!serialisationError) {
        //TODO check for valid baseTypeId (cmis:document, cmis:folder, cmis:relationship, cmis:policy, [cmis:item, cmis:secondary])
        CMISBaseType baseType = [CMISEnums enumForBaseId:[jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONBaseId]];
        switch (baseType) {
            case CMISBaseTypeDocument: {
                typeDef = [CMISDocumentTypeDefinition new];
                ((CMISDocumentTypeDefinition*)typeDef).contentStreamAllowed = [CMISEnums enumForContentStreamAllowed:
                                                                               [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONContentStreamAllowed]];
                ((CMISDocumentTypeDefinition*)typeDef).versionable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONVersionable];
                break;
            }
            case CMISBaseTypeFolder:
                typeDef = [CMISFolderTypeDefinition new];
                break;
                
            case CMISBaseTypeRelationship: {
                typeDef = [CMISRelationshipTypeDefinition new];
                
                id allowedSourceTypes = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAllowedSourceTypes];
                if ([allowedSourceTypes isKindOfClass:NSArray.class]){
                    NSMutableArray *types = [[NSMutableArray alloc] init];
                    for (id type in allowedSourceTypes) {
                        if (type){
                            [types addObject:type];
                        }
                    }
                    ((CMISRelationshipTypeDefinition*)typeDef).allowedSourceTypes = types;
                }
                
                id allowedTargetTypes = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAllowedTargetTypes];
                if ([allowedTargetTypes isKindOfClass:NSArray.class]){
                    NSMutableArray *types = [[NSMutableArray alloc] init];
                    for (id type in allowedTargetTypes) {
                        if (type){
                            [types addObject:type];
                        }
                    }
                    ((CMISRelationshipTypeDefinition*)typeDef).allowedTargetTypes = types;
                }
                break;
            }
            case CMISBaseTypeItem:
                typeDef = [CMISItemTypeDefinition new];
                break;
            case CMISBaseTypeSecondary:
                typeDef = [CMISSecondaryTypeDefinition new];
                break;
            default:
                if (outError != NULL) *outError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument detailedDescription:[NSString stringWithFormat:@"Type '%@' does not match a base type!", [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONBaseId]]];
                return nil;
        }

        typeDef.baseTypeId = baseType;
        typeDef.summary = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDescription];
        typeDef.displayName = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDisplayName];
        typeDef.identifier = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONId];
        typeDef.controllablePolicy = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONControllablePolicy];
        typeDef.controllableAcl = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONControllableAcl];
        typeDef.creatable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONCreateable];
        typeDef.fileable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONFileable];
        typeDef.fullTextIndexed = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONFullTextIndexed];
        typeDef.includedInSupertypeQuery = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONIncludedInSuperTypeQuery];
        typeDef.queryable = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONQueryable];
        typeDef.localName = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalName];
        typeDef.localNamespace = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalNamespace];
        typeDef.parentTypeId = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONParentId];
        typeDef.queryName = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONQueryName];
        
        //TODO type mutability
        
        NSDictionary *propertyDefinitions = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONPropertyDefinitions];
        for (NSDictionary *propertyDefDictionary in [propertyDefinitions allValues]) {
            [typeDef addPropertyDefinition:[CMISBrowserUtil convertPropertyDefinition:propertyDefDictionary]];
        }
        
        // handle extensions
        typeDef.extensions = [CMISObjectConverter convertExtensions:jsonDictionary cmisKeys:[CMISBrowserConstants typeKeys]];
    } else {
        if (outError != NULL) *outError = [CMISErrors cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime];
        return nil;
    }
    
    return typeDef;
}

+ (void)objectDataFromJSONData:(NSData *)jsonData typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void(^)(CMISObjectData *objectData, NSError *error))completionBlock
{
    // TODO: error handling i.e. if jsonData is nil, also handle outError being nil

    // parse the JSON response
    NSError *serialisationError = nil;
    id jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&serialisationError];
    
    if (!serialisationError) {
        // parse the json into a CMISObjectData object
        [CMISBrowserUtil convertObject:jsonDictionary typeCache:typeCache completionBlock:^(CMISObjectData *objectData, NSError *error) {
            completionBlock(objectData, error);
        }];
    } else {
        completionBlock(nil, [CMISErrors cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime]);
    }
}

+ (void)objectListFromJSONData:(NSData *)jsonData typeCache:(CMISBrowserTypeCache *)typeCache isQueryResult:(BOOL)isQueryResult completionBlock:(void(^)(CMISObjectList *objectList, NSError *error))completionBlock
{
    // TODO: error handling i.e. if jsonData is nil, also handle outError being nil
    
    // parse the JSON response
    NSError *serialisationError = nil;
    id jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&serialisationError];
    
    CMISObjectList *objectList = nil;
    if (!serialisationError) {
        // parse the json into a CMISObjectList object
        objectList = [CMISObjectList new];
        
        // parse the objects
        NSArray *objectsArray;
        if ([jsonDictionary isKindOfClass:NSArray.class]){
            objectsArray = jsonDictionary;
            
            objectList.hasMoreItems = NO;
            objectList.numItems = (int)objectsArray.count;
        } else { // is NSDictionary
            if (isQueryResult) {
                objectsArray = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONResults];
            } else {
                objectsArray = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONObjects];
            }
            // retrieve the paging data
            objectList.hasMoreItems = [jsonDictionary cmis_boolForKey:kCMISBrowserJSONHasMoreItems];
            objectList.numItems = [jsonDictionary cmis_intForKey:kCMISBrowserJSONNumberItems];
        }
        
        [CMISBrowserUtil convertObjects:objectsArray typeCache:typeCache completionBlock:^(NSArray *objects, NSError *error) {
            if (error){
                completionBlock(nil, error);
            } else {
                // pass objects to list
                objectList.objects = objects;
                
                // handle extension data
                if([jsonDictionary isKindOfClass:NSDictionary.class]) {
                    if (isQueryResult) {
                        objectList.extensions = [CMISObjectConverter convertExtensions:jsonDictionary cmisKeys:[CMISBrowserConstants queryResultListKeys]];
                    } else {
                        objectList.extensions = [CMISObjectConverter convertExtensions:jsonDictionary cmisKeys:[CMISBrowserConstants objectListKeys]];
                    }
                }
                completionBlock(objectList, nil);
            }
        }];
    } else {
        completionBlock(nil, [CMISErrors cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime]);
    }
}

+ (NSArray *)renditionsFromJSONData:(NSData *)jsonData error:(NSError **)outError
{
    // TODO: error handling i.e. if jsonData is nil, also handle outError being nil
    
    // parse the JSON response
    NSError *serialisationError = nil;
    id jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&serialisationError];
    
    NSArray *renditions = nil;
    if (!serialisationError) {
        // parse the json into a CMISObjectData object
        renditions = [CMISBrowserUtil renditionsFromArray:jsonDictionary];
    } else {
        if (outError != NULL) *outError = [CMISErrors cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime];
        return nil;
    }
    
    return renditions;
}

+ (NSArray *)failedToDeleteObjectsFromJSONData:(NSData *)jsonData error:(NSError **)outError
{
    // TODO: error handling i.e. if jsonData is nil, also handle outError being nil
    
    // parse the JSON response
    NSError *serialisationError = nil;
    id jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&serialisationError];
    
    if (!serialisationError) {
        NSMutableArray *ids = [[NSMutableArray alloc] init];
        NSArray *jsonIds = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONFailedToDeleteId];
        
        if (jsonIds) {
            for (NSObject *obj in jsonIds) {
                [ids addObject:obj.description]; //obj can't be nil as it came out of an array
            }
        }
        
        return ids;
    } else {
        if (outError != NULL) *outError = [CMISErrors cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime];
        return nil;
    }
}

+ (void)objectParents:(NSData *)jsonData typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void(^)(NSArray *objectParents, NSError *error))completionBlock
{
    // TODO: error handling i.e. if jsonData is nil, also handle outError being nil
    
    // parse the JSON response
    NSError *serialisationError = nil;
    id jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&serialisationError];
    
    if (!serialisationError) {
        [self convertObjects:jsonDictionary typeCache:typeCache completionBlock:completionBlock];
    } else {
        completionBlock(nil, [CMISErrors cmisError:serialisationError cmisErrorCode:kCMISErrorCodeRuntime]);
        return;
    }
}

#pragma mark -
#pragma mark Private helper methods

+ (void)convertObject:(NSDictionary *)dictionary typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void(^)(CMISObjectData *objectData, NSError *error))completionBlock
{
    if (!dictionary) {
        completionBlock(nil, nil);
    }
    
    CMISObjectData *objectData = [CMISObjectData new];
    
    BOOL hasSuccinctProperties = YES;
    NSDictionary *propertiesJson = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONSuccinctProperties];
    if(!propertiesJson){
        hasSuccinctProperties = NO;
        propertiesJson = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONProperties];
    }
    
    
    id identifier = [propertiesJson cmis_objectForKeyNotNull:kCMISPropertyObjectId];
    if ([identifier isKindOfClass:NSDictionary.class]){
        objectData.identifier = [identifier cmis_objectForKeyNotNull:kCMISBrowserJSONValue];
    } else {
        objectData.identifier = identifier;
    }
    
    // determine the object type
    id baseType = [propertiesJson cmis_objectForKeyNotNull:kCMISPropertyBaseTypeId];
    if([baseType isKindOfClass:NSDictionary.class]) {
        baseType = [baseType cmis_objectForKeyNotNull:kCMISBrowserJSONValue];
    }
    
    // TODO other base types
    if ([baseType isEqualToString:kCMISPropertyObjectTypeIdValueDocument]) {
        objectData.baseType = CMISBaseTypeDocument;
    } else if ([baseType isEqualToString:kCMISPropertyObjectTypeIdValueFolder]) {
        objectData.baseType = CMISBaseTypeFolder;
    }
    
    objectData.acl = [CMISBrowserUtil convertAcl:[dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAcl]]; //TODO here we should pass isExactAcl:nil!
    
    objectData.allowableActions = [CMISBrowserUtil convertAllowableActions:[dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAllowableActions]];
    
    objectData.isExactAcl = [dictionary cmis_boolForKey:kCMISBrowserJSONIsExact];

    // TODO set policyIds
    
    NSDictionary *propertiesExtension = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONPropertiesExtension];
    
    void (^continueWithObjectConversion)(CMISProperties*, NSError*) = ^(CMISProperties *properties, NSError *error) {
        if (error){
            completionBlock(nil, error);
        } else {
            objectData.properties = properties;
            
            // relationships
            NSArray *relationshipsJson = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONRelationships];
            [CMISBrowserUtil convertObjects:relationshipsJson typeCache:typeCache completionBlock:^(NSArray *objects, NSError *error) {
                if (error){
                    completionBlock(nil, error);
                } else {
                    objectData.relationships = objects;
                    
                    //renditions
                    NSArray *renditionsJson = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONRenditions];
                    objectData.renditions = [self renditionsFromArray:renditionsJson];
                    
                    // handle extensions
                    objectData.extensions = [CMISObjectConverter convertExtensions:dictionary cmisKeys:[CMISBrowserConstants objectKeys]];
                    
                    completionBlock(objectData, nil);
                }
            }];
        }
    };
    
    if(hasSuccinctProperties) {
        [CMISBrowserUtil convertSuccinctProperties:propertiesJson propertiesExtension:propertiesExtension typeCache:typeCache completionBlock:^(CMISProperties *properties, NSError *error) {
            continueWithObjectConversion(properties, error);
        }];
    } else {
        NSError *error = nil;
        CMISProperties *properties = [CMISBrowserUtil convertProperties:propertiesJson propertiesExtension:propertiesExtension error:&error];
        continueWithObjectConversion(properties, error);
    }

}

+ (void)convertObjects:(NSArray *)objectsArray position:(NSInteger)position convertedObjects:(NSMutableArray *)convertedObjects typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void(^)(NSArray* objects, NSError *error))completionBlock
{
    NSDictionary *dictionary = [objectsArray objectAtIndex:position];
    NSDictionary *objectDictionary = [dictionary cmis_objectForKeyNotNull:kCMISBrowserJSONObject];
    if (!objectDictionary) {
        objectDictionary = dictionary;
    }

    if(![objectDictionary isKindOfClass:NSDictionary.class]){
        completionBlock(nil, [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument detailedDescription:[NSString stringWithFormat:@"expected a dictionary but was %@", objectDictionary.class]]);
    }
    [CMISBrowserUtil convertObject:objectDictionary typeCache:typeCache completionBlock:^(CMISObjectData *objectData, NSError *error) {
        if (error){
            completionBlock(nil, error);
        } else {
            if (position == 0) {
                [convertedObjects addObject:objectData];
                completionBlock(convertedObjects, nil);
            } else {
                // TODO check if there is a better way on how to avoid a large call stack
                // We need to do this workaround or else we would end up with a very large call stack
                [CMISBrowserUtil performBlock:^{
                    [self convertObjects:objectsArray
                                position:(position -1)
                        convertedObjects:convertedObjects
                               typeCache:typeCache
                         completionBlock:^(NSArray *objects, NSError *error) {
                             if (error){
                                 completionBlock(nil, error);
                             } else {
                                 [convertedObjects addObject:objectData];
                                 completionBlock(objects, nil);
                             }
                         }];
                }];
            }
        }
    }];

}

+ (void)convertObjects:(NSArray *)objectsArray typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void(^)(NSArray* objects, NSError *error))completionBlock
{
    NSMutableArray *objects = [NSMutableArray arrayWithCapacity:objectsArray.count];
    if (objectsArray.count > 0) {
        [CMISBrowserUtil convertObjects:objectsArray
                               position:(objectsArray.count - 1) // start recursion with last item
                       convertedObjects:objects
                                 typeCache:typeCache
                           completionBlock:^(NSArray *objects, NSError *error) {
                               completionBlock(objects, error);
                           }];
    } else {
        completionBlock([NSArray array], nil);
    }
}

+ (CMISProperties *)convertProperties:(NSDictionary *)propertiesJson propertiesExtension:(NSDictionary *)extJson error:(NSError **)outError
{
    if(!propertiesJson) {
        return nil;
    }
    
    CMISProperties *properties = [[CMISProperties alloc] init];
    
    for (NSString *propName in propertiesJson) {
        NSDictionary *propertyDictionary = [propertiesJson cmis_objectForKeyNotNull:propName];
        if (!propertyDictionary) {
            continue;
        }
        
        CMISPropertyType propertyType = [CMISEnums enumForPropertyType:[propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDatatype]];
        
        id propValue = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONValue];
        NSArray *values = nil;
        if ([propValue isKindOfClass:NSArray.class]) {
            values = propValue;
        } else if (propValue) {
            values = [NSArray arrayWithObject:propValue];
        }
        
        CMISPropertyData *propertyData;
        switch (propertyType) {
            case CMISPropertyTypeString:
            case CMISPropertyTypeId:
            case CMISPropertyTypeBoolean:
            case CMISPropertyTypeInteger:
            case CMISPropertyTypeDecimal:
            case CMISPropertyTypeHtml:
            case CMISPropertyTypeUri:
                propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:values type:propertyType];
                break;
            case CMISPropertyTypeDateTime: {
                NSArray *dateValues = [CMISBrowserUtil convertNumbersToDates:values];
                propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:dateValues type:propertyType];
                break;
            }
            default: {
                if (outError != NULL) *outError = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument
                                                 detailedDescription:@"Unknown property type!"];
                return nil;
            }
        }
        propertyData.identifier = propName;
        propertyData.displayName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDisplayName];
        propertyData.queryName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONQueryName];
        propertyData.localName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalName];
        
        propertyData.extensions = [CMISObjectConverter convertExtensions:propertyDictionary cmisKeys:[CMISBrowserConstants propertyKeys]];
        
        [properties addProperty:propertyData];
    }
    
    if (extJson){
        properties.extensions = [CMISObjectConverter convertExtensions:extJson cmisKeys:[NSSet set]];
    }
    
    return properties;
}

+ (void)convertSuccinctProperties:(NSDictionary *)propertiesJson propertiesExtension:(NSDictionary *)extJson typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void(^)(CMISProperties *properties, NSError *error))completionBlock
{
    if (!propertiesJson) {
        completionBlock(nil, nil);
    }
    
    void (^continueConvertSuccinctPropertiesAndGetSecondaryObjectTypeDefinitions)(CMISTypeDefinition*) = ^(CMISTypeDefinition *typeDef) {
        
        void (^continueConvertSuccinctPropertiesSecondaryObjectTypeDefinitions)(NSArray*) = ^(NSArray *secTypeDefs) {
            
            [self convertProperties:propertiesJson typeCache:typeCache typeDefinition:typeDef secondaryTypeDefinitions:secTypeDefs completionBlock:^(CMISProperties *properties, NSError *error){
                if(error){
                    completionBlock(nil, error);
                } else {
                    if (extJson){
                        properties.extensions = [CMISObjectConverter convertExtensions:extJson cmisKeys:[NSSet set]];
                    }
                    
                    completionBlock(properties, nil);
                }
            }];
        };
        
        // Get secondary object type definitions
        NSArray *secTypeIds = [propertiesJson cmis_objectForKeyNotNull:kCMISPropertySecondaryObjectTypeIds];
        if (secTypeIds != nil && secTypeIds.count > 0) {
            [CMISBrowserUtil retrieveTypeDefinitions:secTypeIds typeCache:typeCache completionBlock:^(NSArray *typeDefinitions, NSError *error) {
                if(error){
                    completionBlock(nil, error);
                } else {
                    continueConvertSuccinctPropertiesSecondaryObjectTypeDefinitions(typeDefinitions);
                }
            }];
        } else {
            continueConvertSuccinctPropertiesSecondaryObjectTypeDefinitions(nil);
        }
    };
    
    // Get type definition for given object type id
    CMISTypeDefinition *typeDef = nil;
    if ([[propertiesJson cmis_objectForKeyNotNull:kCMISPropertyObjectTypeId] isKindOfClass:NSString.class]){
        [typeCache typeDefinition:[propertiesJson cmis_objectForKeyNotNull:kCMISPropertyObjectTypeId] completionBlock:^(CMISTypeDefinition *typeDef, NSError *error){
            if(error){
                completionBlock(nil, error);
            } else {
                continueConvertSuccinctPropertiesAndGetSecondaryObjectTypeDefinitions(typeDef);
            }
        }];
    } else {
        continueConvertSuccinctPropertiesAndGetSecondaryObjectTypeDefinitions(typeDef);
    }
}

+(void)convertProperty:(NSString *)propName propertiesJson:(NSDictionary *)propertiesJson typeCache:(CMISBrowserTypeCache *)typeCache typeDefinition:(CMISTypeDefinition *)typeDef secondaryTypeDefinitions:(NSArray *)secTypeDefs completionBlock:(void(^)(CMISPropertyData *propertyData, NSError *error))completionBlock {
    CMISPropertyDefinition *propDef = nil;
    if (typeDef){
        propDef = typeDef.propertyDefinitions[propName];
    }
    
    if (propDef == nil && secTypeDefs != nil) {
        for (CMISTypeDefinition *secTypeDef in secTypeDefs) {
            propDef = secTypeDef.propertyDefinitions[propName];
            if (propDef){
                break;
            }
        }
    }
    
    void (^continueConvertSuccinctPropertiesTypeDefinitionDocument)(CMISPropertyDefinition*) = ^(CMISPropertyDefinition *propDef) {
        
        void (^continueConvertSuccinctPropertiesTypeDefinitionFolder)(CMISPropertyDefinition*) = ^(CMISPropertyDefinition *propDef) {
            
            id propValue = [propertiesJson cmis_objectForKeyNotNull:propName];
            NSArray *values = nil;
            if ([propValue isKindOfClass:NSArray.class]) {
                values = propValue;
            } else if (propValue) {
                values = [NSArray arrayWithObject:propValue];
            }
            
            CMISPropertyData *propertyData;
            
            if (propDef){
                
                switch (propDef.propertyType) {
                    case CMISPropertyTypeString:
                    case CMISPropertyTypeId:
                    case CMISPropertyTypeBoolean:
                    case CMISPropertyTypeInteger:
                    case CMISPropertyTypeDecimal:
                    case CMISPropertyTypeHtml:
                    case CMISPropertyTypeUri:
                        propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:values type:propDef.propertyType];
                        break;
                    case CMISPropertyTypeDateTime: {
                        NSArray *dateValues = [CMISBrowserUtil convertNumbersToDates:values];
                        propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:dateValues type:propDef.propertyType];
                        break;
                    }
                    default: {
                        NSError *error = [CMISErrors createCMISErrorWithCode:kCMISErrorCodeInvalidArgument
                                                         detailedDescription:@"Unknown property type!"];
                        completionBlock(nil, error);
                        return;
                    }
                }
                propertyData.identifier = propName;
                propertyData.displayName = propDef.displayName;
                propertyData.queryName = propDef.queryName;
                propertyData.localName = propDef.localName;
            } else {
                // this else block should only be reached in rare circumstances
                // it may return incorrect types
                if (values == nil) {
                    propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:nil type:CMISPropertyTypeString];
                } else {
                    id firstValue = values[0];
                    if ([firstValue isKindOfClass:NSNumber.class]) {
                        propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:values type:CMISPropertyTypeInteger];
                    } else {
                        propertyData = [CMISPropertyData createPropertyForId:propName arrayValue:values type:CMISPropertyTypeString];
                    }
                }
                
                propertyData.identifier = propName;
                propertyData.displayName = propName;
                propertyData.queryName = nil;
                propertyData.localName = nil;
            }
            
            completionBlock(propertyData, nil);
        };
        
        if (!propDef) { //try to find property definition on folder
            [typeCache typeDefinition:kCMISPropertyObjectTypeIdValueFolder completionBlock:^(CMISTypeDefinition *typeDefinition, NSError *error) {
                if (error){
                    completionBlock(nil, error);
                } else {
                    CMISPropertyDefinition *propertyDefinition = typeDefinition.propertyDefinitions[propName];
                    continueConvertSuccinctPropertiesTypeDefinitionFolder(propertyDefinition);
                }
            }];
        } else {
            continueConvertSuccinctPropertiesTypeDefinitionFolder(propDef);
        }
        
    };
    
    if (!propDef) { //try to find property definition on document
        [typeCache typeDefinition:kCMISPropertyObjectTypeIdValueDocument completionBlock:^(CMISTypeDefinition *typeDefinition, NSError *error) {
            if (error){
                completionBlock(nil, error);
            } else {
                CMISPropertyDefinition *propertyDefinition = typeDefinition.propertyDefinitions[propName];
                continueConvertSuccinctPropertiesTypeDefinitionDocument(propertyDefinition);
            }
        }];
    } else {
        continueConvertSuccinctPropertiesTypeDefinitionDocument(propDef);
    }
}

+ (NSArray *)convertNumbersToDates:(NSArray *)numbers
{
    if(!numbers) {
        return nil;
    }
    
    NSMutableArray *dates = [[NSMutableArray alloc] initWithCapacity:numbers.count];
    for (NSNumber *miliseconds in numbers) {
        NSDate *date = [NSDate dateWithTimeIntervalSince1970:[miliseconds unsignedLongLongValue] / 1000.0]; // miliseconds to seconds
        [dates addObject:date];
    }
    return dates;
}

+ (void)convertProperties:(NSArray*)propNames position:(NSInteger)position properties:(CMISProperties *)properties propertiesJson:(NSDictionary *)propertiesJson typeCache:(CMISBrowserTypeCache *)typeCache typeDefinition:(CMISTypeDefinition *)typeDef secondaryTypeDefinitions:(NSArray *)secTypeDefs completionBlock:(void (^)(CMISProperties *properties, NSError *error))completionBlock
{
    NSString *propName = [propNames objectAtIndex:position];
    
    [self convertProperty:propName
           propertiesJson:propertiesJson
                typeCache:typeCache
           typeDefinition:typeDef
 secondaryTypeDefinitions:secTypeDefs
          completionBlock:^(CMISPropertyData *propertyData, NSError *error) {
              if (error){
                  completionBlock(nil, error);
              } else {
                  if (position == 0) {
                      [properties addProperty:propertyData];
                      completionBlock(properties, nil);
                  } else {
                      // TODO check if there is a better way on how to avoid a large call stack
                      // We need to do this workaround or else we would end up with a very large call stack
                      [CMISBrowserUtil performBlock:^{
                          [self convertProperties:propNames
                                         position:(position -1)
                                       properties:properties
                                   propertiesJson:propertiesJson
                                        typeCache:typeCache
                                   typeDefinition:typeDef
                         secondaryTypeDefinitions:secTypeDefs
                                  completionBlock:^(CMISProperties *properties, NSError *error) {
                                      if (error){
                                          completionBlock(nil, error);
                                      } else {
                                          [properties addProperty:propertyData];
                                          completionBlock(properties, nil);
                                      }
                                  }];
                      }];
                  }
              }
          }];
}

+ (void)convertProperties:(NSDictionary *)propertiesJson typeCache:(CMISBrowserTypeCache *)typeCache typeDefinition:(CMISTypeDefinition *)typeDef secondaryTypeDefinitions:(NSArray *)secTypeDefs completionBlock:(void(^)(CMISProperties *properties, NSError *error))completionBlock
{
    // create properties
    CMISProperties *properties = [CMISProperties new];
    
    NSArray *propNames = [propertiesJson allKeys];
    if (propNames.count > 0) {
        [CMISBrowserUtil convertProperties:propNames
                                        position:(propNames.count - 1) // start recursion with last item
                                properties:properties
                            propertiesJson:propertiesJson
                                 typeCache:typeCache
                            typeDefinition:typeDef
                  secondaryTypeDefinitions:secTypeDefs
                           completionBlock:^(CMISProperties *properties, NSError *error) {
                                     completionBlock(properties, error);
                                 }];
    } else {
        completionBlock(properties, nil);
    }
}

+ (CMISRepositoryCapabilities *)convertRepositoryCapabilities:(NSDictionary *)jsonDictionary
{
    if (!jsonDictionary){
        return nil;
    }
    
    CMISRepositoryCapabilities *result = [[CMISRepositoryCapabilities alloc] init];
    for (NSString *capabilityKey in jsonDictionary) {
        id value = [jsonDictionary cmis_objectForKeyNotNull:capabilityKey];
        
        if([[CMISConstants repositoryCapabilityKeys] containsObject:capabilityKey]) {
            [result setCapability:capabilityKey value:value];
        }
    }
    
    result.extensions = [CMISObjectConverter convertExtensions:jsonDictionary cmisKeys:[CMISConstants repositoryCapabilityKeys]];
    
    return result;
}

+ (CMISAcl *)convertAcl:(NSDictionary *)jsonDictionary
{
    if (!jsonDictionary) {
        return nil;
    }
    
    CMISAcl *result = [[CMISAcl alloc] init];
    
    NSMutableArray *aces = [[NSMutableArray alloc] init];
    
    NSArray *jsonAces = [jsonDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONAces];
    if (jsonAces) {
        for (NSDictionary *entry in jsonAces) {
            CMISAce *ace = [[CMISAce alloc] init];
            
            id isDirect = [entry cmis_objectForKeyNotNull:kCMISBrowserJSONAceIsDirect];
            ace.isDirect = isDirect != nil ? [isDirect boolValue] : YES;
            
            NSArray *jsonPermissions = [entry cmis_objectForKeyNotNull:kCMISBrowserJSONAcePermissions];
            if (jsonPermissions) {
                NSMutableSet *permissions = [[NSMutableSet alloc] init];
                for (NSObject *perm in jsonPermissions) {
                    [permissions addObject:[perm description]];
                }
                ace.permissions = permissions;
            }
            
            NSDictionary *jsonPrincipal = [entry cmis_objectForKeyNotNull:kCMISBrowserJSONAcePrincipal];
            if (jsonPrincipal) {
                CMISPrincipal *principal = [[CMISPrincipal alloc] init];
                
                principal.principalId = [jsonPrincipal cmis_objectForKeyNotNull:kCMISBrowserJSONAcePrincipalId];
                
                principal.extensions = [CMISObjectConverter convertExtensions:jsonPrincipal cmisKeys:[CMISBrowserConstants principalKeys]];
                
                ace.principal = principal;
            }
            
            ace.extensions = [CMISObjectConverter convertExtensions:entry cmisKeys:[CMISBrowserConstants aceKeys]];
            
            [aces addObject:ace];
        }
    }
    
    result.aces = [aces copy];
    
    //TODO result.isExact = isExact; // there should be a "isExcat" parameter of this method
    
    result.extensions = [CMISObjectConverter convertExtensions:jsonDictionary cmisKeys:[CMISBrowserConstants aclKeys]];
    
    return result;
}

+ (CMISAllowableActions *)convertAllowableActions:(NSDictionary *)jsonDictionary
{
    if (!jsonDictionary) {
        return nil;
    }
    
    NSArray *extensions = [CMISObjectConverter convertExtensions:jsonDictionary cmisKeys:[NSSet setWithObjects:CMISAllowableActionsArray]];
    CMISAllowableActions *result = [[CMISAllowableActions alloc] initWithAllowableActionsDictionary:jsonDictionary extensionElementArray:extensions];

    return result;
}

+ (void)retrieveTypeDefinitions:(NSArray *)objectTypeIds position:(NSInteger)position typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void (^)(NSMutableArray *typeDefinitions, NSError *error))completionBlock
{
    [typeCache typeDefinition:[objectTypeIds objectAtIndex:position]
              completionBlock:^(CMISTypeDefinition *typeDefinition, NSError *error) {
                             if (error){
                                 completionBlock(nil, error);
                             } else {
                                 if (position == 0) {
                                     NSMutableArray *typeDefinitions = [[NSMutableArray alloc] initWithCapacity:objectTypeIds.count];
                                     [typeDefinitions addObject:typeDefinition];
                                     completionBlock(typeDefinitions, error);
                                 } else {
                                     [self retrieveTypeDefinitions:objectTypeIds position:(position - 1) typeCache:typeCache completionBlock:^(NSMutableArray *typeDefinitions, NSError *error) {
                                         if(error) {
                                             completionBlock(nil, error);
                                         } else {
                                             [typeDefinitions addObject:typeDefinition];
                                             completionBlock(typeDefinitions, nil);
                                         }
                                     }];
                                 }
                             }
                         }];
}

+ (void)retrieveTypeDefinitions:(NSArray *)objectTypeIds typeCache:(CMISBrowserTypeCache *)typeCache completionBlock:(void (^)(NSArray *typeDefinitions, NSError *error))completionBlock
{
    if (objectTypeIds.count > 0) {
        [CMISBrowserUtil retrieveTypeDefinitions:objectTypeIds
                                        position:(objectTypeIds.count - 1) // start recursion with last item
                                       typeCache:typeCache
                                 completionBlock:^(NSMutableArray *typeDefinitions, NSError *error) {
                                     completionBlock(typeDefinitions, error);
                                 }];
    } else {
        completionBlock([[NSArray alloc] init], nil);
    }
}

+ (NSArray *)renditionsFromArray:(NSArray *)array
{
    if (!array) {
        return nil;
    }
    NSMutableArray *renditions = [[NSMutableArray alloc] initWithCapacity:array.count];
    for(NSDictionary *renditionJson in array){
        CMISRenditionData *renditionData = [CMISRenditionData new];
        renditionData.height = [NSNumber numberWithLongLong:[[renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionHeight] longLongValue]];
        renditionData.kind = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionKind];
        renditionData.length = [NSNumber numberWithLongLong:[[renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionLength] longLongValue]];
        renditionData.mimeType = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionMimeType];
        renditionData.renditionDocumentId = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionDocumentId];
        renditionData.streamId = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionStreamId];
        renditionData.title = [renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionTitle];
        renditionData.width = [NSNumber numberWithLongLong:[[renditionJson cmis_objectForKeyNotNull:kCMISBrowserJSONRenditionWidth] longLongValue]];
        
        // handle extensions
        renditionData.extensions = [CMISObjectConverter convertExtensions:renditionJson cmisKeys:[CMISBrowserConstants renditionKeys]];
        
        [renditions addObject:renditionData];
    }
    
    return renditions;
}

+ (CMISPropertyDefinition *)convertPropertyDefinition:(NSDictionary *)propertyDictionary
{
    if (!propertyDictionary){
        return nil;
    }
    
    // create property definition and add to type definition
    CMISPropertyDefinition *propDef = [CMISPropertyDefinition new];
    propDef.identifier = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONId];
    propDef.localName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalName];
    propDef.localNamespace = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONLocalNamespace];
    propDef.queryName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONQueryName];
    propDef.summary = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDescription];
    propDef.displayName = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDisplayName];
    propDef.inherited = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONInherited];
    propDef.openChoice = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONOpenChoice];
    propDef.orderable = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONOrderable];
    propDef.queryable = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONQueryable];
    propDef.required = [propertyDictionary cmis_boolForKey:kCMISBrowserJSONRequired];
    
    // determine property type
    propDef.propertyType = [CMISEnums enumForPropertyType:[propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONPropertyType]];
    
    // determine cardinality
    NSString *cardinalityString = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONCardinality];
    if ([cardinalityString isEqualToString:kCMISBrowserJSONCardinalityValueSingle]) {
        propDef.cardinality = CMISCardinalitySingle;
    } else if ([cardinalityString isEqualToString:kCMISBrowserJSONCardinalityValueMultiple]) {
        propDef.cardinality = CMISCardinalityMulti;
    }
    
    // determine updatability
    NSString *updatabilityString = [propertyDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONUpdateability];
    if ([updatabilityString isEqualToString:kCMISBrowserJSONUpdateabilityValueReadOnly]) {
        propDef.updatability = CMISUpdatabilityReadOnly;
    } else if ([updatabilityString isEqualToString:kCMISBrowserJSONUpdateabilityValueReadWrite]) {
        propDef.updatability = CMISUpdatabilityReadWrite;
    } else if ([updatabilityString isEqualToString:kCMISBrowserJSONUpdateabilityValueOnCreate]) {
        propDef.updatability = CMISUpdatabilityOnCreate;
    } else if ([updatabilityString isEqualToString:kCMISBrowserJSONUpdateabilityValueWhenCheckedOut]) {
        propDef.updatability = CMISUpdatabilityWhenCheckedOut;
    }
    
    // parse default value
    id defaultValueObject = propertyDictionary[kCMISBrowserJSONDefaultValue];
    if (defaultValueObject != nil)
    {
        // for single valued properties this will be actual default value,
        // for multi valued properties this will be an array
        if ([defaultValueObject isKindOfClass:[NSArray class]])
        {
            propDef.defaultValues = defaultValueObject;
        }
        else
        {
            propDef.defaultValues = @[defaultValueObject];
        }
    }
    
    // parse choices, if present
    NSArray *choicesJSON = propertyDictionary[kCMISBrowserJSONChoice];
    if (choicesJSON != nil) {
        NSMutableArray *choices = [NSMutableArray array];
        for (NSDictionary *choiceDictionary in choicesJSON) {
            CMISPropertyChoice *choice = [CMISPropertyChoice new];
            choice.displayName = [choiceDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONDisplayName];
            choice.value = [choiceDictionary cmis_objectForKeyNotNull:kCMISBrowserJSONValue];
            [choices addObject:choice];
        }
        
        propDef.choices = choices;
    }
    
    // handle extensions
    propDef.extensions = [CMISObjectConverter convertExtensions:propertyDictionary cmisKeys:[CMISBrowserConstants propertyTypeKeys]];
    
    return propDef;
}


@end
