class ClientProcessor {

    public Boolean processCaseModel(JSONObject event, JSONObject client, JSONArray createsCase) {
        try {

            if (createsCase == null || createsCase.length() == 0) {
                return false;
            }
            for (int openCase = 0; openCase < createsCase.length(); openCase++) {

                String clientType = createsCase.getString(openCase);

                JSONObject columnMappings = getColumnMappings(clientType);
                JSONArray columns = columnMappings.getJSONArray("columns");
                String baseEntityId = client.getString(baseEntityIdJSONKey);
                String expectedEncounterType =
                        event.has("eventType") ? event.getString("eventType") : null;

                ContentValues contentValues = new ContentValues();
                //Add the base_entity_id
                contentValues.put("base_entity_id", baseEntityId);
                contentValues.put("is_closed", 0);

                for (int i = 0; i < columns.length(); i++) {
                    JSONObject colObject = columns.getJSONObject(i);
                    String docType = colObject.getString("type");
                    String columnName = colObject.getString("column_name");
                    JSONObject jsonMapping = colObject.getJSONObject("json_mapping");
                    String dataSegment = null;
                    String fieldName = jsonMapping.getString("field");
                    String fieldValue = null;
                    String responseKey = null;

                    if (fieldName != null && fieldName.contains(".")) {
                        String fieldNameArray[] = fieldName.split("\\.");
                        dataSegment = fieldNameArray[0];
                        fieldName = fieldNameArray[1];
                        fieldValue = jsonMapping.has("concept") ? jsonMapping.getString("concept")
                                : (jsonMapping.has("formSubmissionField") ? jsonMapping
                                .getString("formSubmissionField") : null);
                        if (fieldValue != null) {
                            responseKey = VALUES_KEY;
                        }
                    }

                    JSONObject jsonDocument = docType.equalsIgnoreCase("Event") ? event : client;

                    Object jsonDocSegment;

                    if (dataSegment != null) {
                        // pick data from a specific section of the doc
                        jsonDocSegment =
                                jsonDocument.has(dataSegment) ? jsonDocument.get(dataSegment)
                                        : null;

                    } else {
                        // else the use the main doc as the doc segment
                        jsonDocSegment = jsonDocument;
                    }

                    // special handler needed to process address,
                    if (dataSegment != null && dataSegment.equalsIgnoreCase("addresses")) {
                        Map<String, String> addressMap = getClientAddressAsMap(client);
                        if (addressMap.containsKey(fieldName)) {
                            contentValues.put(columnName, addressMap.get(fieldName));
                        }
                        continue;
                    }

                    // special handler for relationalid
                    if (dataSegment != null && dataSegment.equalsIgnoreCase("relationships")) {
                        JSONObject relationshipsObject = jsonDocument
                                .getJSONObject("relationships");
                        JSONArray relationshipsArray = relationshipsObject.getJSONArray(fieldName);

                        if (relationshipsArray != null && relationshipsArray.length() > 0) {
                            List<String> relationalIds = getValues(relationshipsArray);
                            contentValues.put(columnName, relationalIds.get(0));

                        }

                        continue;
                    }

                    String encounterType =
                            jsonMapping.has("event_type") ? jsonMapping.getString("event_type")
                                    : null;

                    if (jsonDocSegment instanceof JSONArray) {

                        JSONArray jsonDocSegmentArray = (JSONArray) jsonDocSegment;

                        for (int j = 0; j < jsonDocSegmentArray.length(); j++) {
                            JSONObject jsonDocObject = jsonDocSegmentArray.getJSONObject(j);
                            String columnValue = null;

                            if (fieldValue == null) {
                                // This means field_value and response_key are null so pick the
                                // value from the json object for the field_name
                                if (jsonDocObject.has(fieldName)) {
                                    columnValue = jsonDocObject.getString(fieldName);
                                }
                            } else {
                                // this means field_value and response_key are not null e.g when
                                // retrieving some value in the events obs section
                                String expectedFieldValue = jsonDocObject.getString(fieldName);
                                // some events can only be differentiated by the event_type value
                                // eg pnc1,pnc2, anc1,anc2
                                // check if encountertype (the one in ec_client_fields.json) is
                                // null or it matches the encounter type from the ec doc we're
                                // processing
                                boolean encounterTypeMatches =
                                        (encounterType == null) || (encounterType != null
                                                && encounterType
                                                .equalsIgnoreCase(expectedEncounterType));

                                if (encounterTypeMatches && expectedFieldValue
                                        .equalsIgnoreCase(fieldValue)) {
                                    columnValue = getValues(jsonDocObject.get(responseKey)).get(0);
                                }
                            }

                            // after successfully retrieving the column name and value store it
                            // in Content value
                            if (columnValue != null) {
                                columnValue = getHumanReadableConceptResponse(columnValue,
                                        jsonDocObject);
                                contentValues.put(columnName, columnValue);
                            }
                        }

                    } else {
                        //e.g client attributes section
                        String columnValue = null;
                        JSONObject jsonDocSegmentObject = (JSONObject) jsonDocSegment;
                        columnValue = jsonDocSegmentObject.has(fieldName) ? jsonDocSegmentObject
                                .getString(fieldName) : "";

                        // after successfully retrieving the column name and value store it in
                        // Content value
                        if (columnValue != null) {
                            columnValue = getHumanReadableConceptResponse(columnValue,
                                    jsonDocSegmentObject);
                            contentValues.put(columnName, columnValue);
                        }
                    }
                }

                // Modify openmrs generated identifier, Remove hyphen if it exists
                updateIdenitifier(contentValues);

                // save the values to db
                Long id = executeInsertStatement(contentValues, clientType);
                updateFTSsearch(clientType, baseEntityId, contentValues);
                Long timestamp = getEventDate(event.get("eventDate"));
                addContentValuesToDetailsTable(contentValues, timestamp);
                updateClientDetailsTable(event, client);
            }

            return true;
        } catch (Exception e) {
            Timber.e(e);

            return null;
        }

    }

    public  ClientProcessor(Context context);

}