summaryrefslogtreecommitdiffstats
path: root/modules-available
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available')
-rw-r--r--modules-available/adduser/config.json3
-rw-r--r--modules-available/adduser/lang/de/messages.json10
-rw-r--r--modules-available/adduser/lang/de/module.json3
-rw-r--r--modules-available/adduser/lang/de/permissions.json6
-rw-r--r--modules-available/adduser/lang/de/template-tags.json23
-rw-r--r--modules-available/adduser/lang/en/messages.json10
-rw-r--r--modules-available/adduser/lang/en/module.json3
-rw-r--r--modules-available/adduser/lang/en/permissions.json6
-rw-r--r--modules-available/adduser/lang/en/template-tags.json21
-rw-r--r--modules-available/adduser/page.inc.php240
-rw-r--r--modules-available/adduser/permissions/permissions.json14
-rw-r--r--modules-available/adduser/style.css19
-rw-r--r--modules-available/adduser/templates/header.html3
-rw-r--r--modules-available/adduser/templates/js-add-edit.html29
-rw-r--r--modules-available/adduser/templates/page-adduser.html67
-rw-r--r--modules-available/adduser/templates/page-edituser.html74
-rw-r--r--modules-available/adduser/templates/page-userlist.html87
-rw-r--r--modules-available/adduser/templates/user-permissions.html34
-rw-r--r--modules-available/backup/config.json4
-rw-r--r--modules-available/backup/page.inc.php15
-rw-r--r--modules-available/backup/permissions/permissions.json12
-rw-r--r--modules-available/backup/style.css7
-rw-r--r--modules-available/backup/templates/_page.html14
-rw-r--r--modules-available/baseconfig/api.inc.php23
-rw-r--r--modules-available/baseconfig/config.json7
-rw-r--r--modules-available/baseconfig/lang/de/permissions.json4
-rw-r--r--modules-available/baseconfig/lang/en/permissions.json4
-rw-r--r--modules-available/baseconfig/page.inc.php42
-rw-r--r--modules-available/baseconfig/permissions/permissions.json8
-rw-r--r--modules-available/baseconfig/templates/_page.html11
-rw-r--r--modules-available/baseconfig_bwidm/config.json6
-rw-r--r--modules-available/baseconfig_bwidm/hooks/translation.inc.php4
-rw-r--r--modules-available/baseconfig_bwlp/baseconfig/settings.json18
-rw-r--r--modules-available/baseconfig_bwlp/config.json6
-rw-r--r--modules-available/baseconfig_bwlp/hooks/translation.inc.php4
-rw-r--r--modules-available/baseconfig_bwlp/lang/de/config-variables.json5
-rw-r--r--modules-available/baseconfig_bwlp/lang/en/config-variables.json7
-rw-r--r--modules-available/baseconfig_partitions_cdn/config.json8
-rw-r--r--modules-available/baseconfig_partitions_cdn/lang/de/permissions.json7
-rw-r--r--modules-available/baseconfig_partitions_cdn/lang/en/permissions.json7
-rw-r--r--modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json4
-rw-r--r--modules-available/baseconfig_partitions_cdn/page.inc.php41
-rw-r--r--modules-available/baseconfig_partitions_cdn/permissions/permissions.json17
-rw-r--r--modules-available/baseconfig_partitions_cdn/style.css4
-rw-r--r--modules-available/baseconfig_partitions_cdn/templates/_page.html60
-rw-r--r--modules-available/bootstrap_datepicker/config.json17
-rw-r--r--modules-available/bootstrap_dialog/config.json17
-rw-r--r--modules-available/bootstrap_multiselect/config.json17
-rw-r--r--modules-available/bootstrap_switch/config.json13
-rw-r--r--modules-available/bootstrap_timepicker/config.json17
-rw-r--r--modules-available/citymanagement/config.json6
-rw-r--r--modules-available/dnbd3/config.json9
-rw-r--r--modules-available/dnbd3/hooks/main-warning.inc.php2
-rw-r--r--modules-available/dnbd3/hooks/runmode/config.json5
-rw-r--r--modules-available/dnbd3/inc/dnbd3util.inc.php52
-rw-r--r--modules-available/dnbd3/lang/de/permissions.json8
-rw-r--r--modules-available/dnbd3/lang/de/template-tags.json18
-rw-r--r--modules-available/dnbd3/lang/en/permissions.json8
-rw-r--r--modules-available/dnbd3/lang/en/template-tags.json12
-rw-r--r--modules-available/dnbd3/page.inc.php178
-rw-r--r--modules-available/dnbd3/permissions/permissions.json20
-rw-r--r--modules-available/dnbd3/templates/page-proxy-altservers.html12
-rw-r--r--modules-available/dnbd3/templates/page-proxy-clients.html69
-rw-r--r--modules-available/dnbd3/templates/page-proxy-config.html20
-rw-r--r--modules-available/dnbd3/templates/page-proxy-header.html3
-rw-r--r--modules-available/dnbd3/templates/page-proxy-images.html31
-rw-r--r--modules-available/dnbd3/templates/page-proxy-loclist.html27
-rw-r--r--modules-available/dnbd3/templates/page-proxy-stats.html30
-rw-r--r--modules-available/dnbd3/templates/page-serverlist.html55
-rw-r--r--modules-available/dozmod/api.inc.php12
-rw-r--r--modules-available/dozmod/config.json4
-rw-r--r--modules-available/dozmod/hooks/main-warning.inc.php12
-rw-r--r--modules-available/dozmod/lang/de/messages.json20
-rw-r--r--modules-available/dozmod/lang/de/module.json6
-rw-r--r--modules-available/dozmod/lang/de/permissions.json31
-rw-r--r--modules-available/dozmod/lang/de/template-tags.json58
-rw-r--r--modules-available/dozmod/lang/en/messages.json20
-rw-r--r--modules-available/dozmod/lang/en/module.json6
-rw-r--r--modules-available/dozmod/lang/en/permissions.json31
-rw-r--r--modules-available/dozmod/lang/en/template-tags.json56
-rw-r--r--modules-available/dozmod/page.inc.php349
-rw-r--r--modules-available/dozmod/pages/actionlog.inc.php (renamed from modules-available/dozmod/inc/pagedozmodlog.inc.php)72
-rw-r--r--modules-available/dozmod/pages/expiredimages.inc.php97
-rw-r--r--modules-available/dozmod/pages/ldapfilters.inc.php119
-rw-r--r--modules-available/dozmod/pages/mailconfig.inc.php96
-rw-r--r--modules-available/dozmod/pages/networkrules.inc.php98
-rw-r--r--modules-available/dozmod/pages/networkshares.inc.php108
-rw-r--r--modules-available/dozmod/pages/runscripts.inc.php133
-rw-r--r--modules-available/dozmod/pages/runtimeconfig.inc.php112
-rw-r--r--modules-available/dozmod/pages/templates.inc.php (renamed from modules-available/dozmod/inc/pagemailtemplates.inc.php)51
-rw-r--r--modules-available/dozmod/pages/users.inc.php (renamed from modules-available/dozmod/inc/pagedozmodusers.inc.php)51
-rw-r--r--modules-available/dozmod/permissions/permissions.json73
-rw-r--r--modules-available/dozmod/style.css20
-rw-r--r--modules-available/dozmod/templates/actionlog-log.html6
-rw-r--r--modules-available/dozmod/templates/images-delete.html1
-rw-r--r--modules-available/dozmod/templates/ldapfilter-add.html39
-rw-r--r--modules-available/dozmod/templates/ldapfilters.html77
-rw-r--r--modules-available/dozmod/templates/mailconfig.html7
-rw-r--r--modules-available/dozmod/templates/networkrules-edit.html43
-rw-r--r--modules-available/dozmod/templates/networkrules.html82
-rw-r--r--modules-available/dozmod/templates/networkshares-edit.html84
-rw-r--r--modules-available/dozmod/templates/networkshares.html113
-rw-r--r--modules-available/dozmod/templates/runscripts-edit.html89
-rw-r--r--modules-available/dozmod/templates/runscripts-list.html89
-rw-r--r--modules-available/dozmod/templates/runtimeconfig.html5
-rw-r--r--modules-available/dozmod/templates/templates.html7
-rw-r--r--modules-available/dozmod/templates/userlist.html8
-rw-r--r--modules-available/eventlog/config.json4
-rw-r--r--modules-available/eventlog/page.inc.php45
-rw-r--r--modules-available/eventlog/permissions/permissions.json8
-rw-r--r--modules-available/exams/baseconfig/getconfig.inc.php39
-rw-r--r--modules-available/exams/config.json13
-rw-r--r--modules-available/exams/lang/de/permissions.json7
-rw-r--r--modules-available/exams/lang/de/template-tags.json4
-rw-r--r--modules-available/exams/lang/en/permissions.json7
-rw-r--r--modules-available/exams/lang/en/template-tags.json4
-rw-r--r--modules-available/exams/page.inc.php306
-rw-r--r--modules-available/exams/permissions/permissions.json13
-rw-r--r--modules-available/exams/templates/page-add-edit-exam.html6
-rw-r--r--modules-available/exams/templates/page-exams.html8
-rw-r--r--modules-available/imgmanagement/config.json6
-rw-r--r--modules-available/internetaccess/config.json4
-rw-r--r--modules-available/internetaccess/permissions/permissions.json8
-rw-r--r--modules-available/js_chart/config.json10
-rw-r--r--modules-available/js_circles/config.json10
-rw-r--r--modules-available/js_jqueryui/config.json17
-rw-r--r--modules-available/js_moment/config.json14
-rw-r--r--modules-available/js_selectize/config.json17
-rw-r--r--modules-available/js_stupidtable/clientscript.js354
-rw-r--r--modules-available/js_stupidtable/config.json10
-rw-r--r--modules-available/js_stupidtable/style.css3
-rw-r--r--modules-available/js_vis/config.json19
-rwxr-xr-xmodules-available/js_weekcalendar/clientscript.js2
-rw-r--r--modules-available/locationinfo/api.inc.php23
-rw-r--r--modules-available/locationinfo/config.json11
-rw-r--r--modules-available/locationinfo/exchange-includes/README4
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppManifestsType.php28
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppsType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfArraysOfTrackingPropertiesType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttachmentsType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttendeeConflictData.php59
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBaseItemIdsType.php28
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBinaryType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBodyContentAttributedValuesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarEvent.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarPermissionsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfContextProperty.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationNodesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDLExpansionType.php76
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserResponseMessageType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDiscoverySearchConfigurationType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressAttributedValuesType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEncryptedSharedFolderDataType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedAttributesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedPropertyAttributedValueType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFailedSearchMailboxesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFindMessageTrackingSearchResultType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFolderIdType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFoldersType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFreeBusyResponse.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfGroupedItemsType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfImGroupType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfInvalidRecipientsType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfItemClassType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfKeywordStatisticsSearchResultsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailTipsResponseMessageType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxData.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxHoldStatusType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemDetailsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemStatisticsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfOccurrenceRangesType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleQuerySource.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPermissionsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPersonaAttributionsType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPhoneNumberAttributedValuesType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPostalAddressAttributedValuesType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPrivateCatalogAddInsType.php29
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfProtectionRulesType.php29
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRealItemsType.php115
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientTrackingEventType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRemindersType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResolutionType.php76
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResponseMessagesType.php504
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRetentionPolicyTagsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRoomsType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationErrorsType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationsType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleValidationErrorsType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRulesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchItemKindsType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchPreviewItemsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchableMailboxesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationResponseMessageType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSmtpAddressType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringArrayAttributedValuesType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringAttributedValuesType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestion.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestionDayResult.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTimeZoneDefinitionType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTrackingPropertiesType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsGroupsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUnknownEntriesType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserIdType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserMailboxesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfValueAttributionsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfWorkingPeriod.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAllItemsType.php217
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAlternateIdsType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfApplyConversationActionType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttachmentsType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttendeesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseFolderIdsType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseItemIdsType.php56
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfClientAccessTokenRequestsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfDeletedOccurrencesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedFieldURIs.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedPropertyType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFieldOrdersType.php30
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangeDescriptionsType.php49
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderNamesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFoldersType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfGroupIdentifiersType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfInternetHeadersType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangeDescriptionsType.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangesType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemIdsType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxQueriesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxSearchScopesType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationEventTypesType.php29
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationsType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfOccurrenceInfoType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPathsToElementType.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPeriodsType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPropertyValuesType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfReminderItemActionType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRequestAttachmentIdsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfResponseObjectsType.php128
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRestrictedGroupIdentifiersType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfSubscriptionIdsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfTimeZoneIdType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfUploadItemsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayofLegacyDNsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Autodiscover.php896
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ClassMap.php684
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php1702
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AddInStateType.php84
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AffectedTaskOccurrencesType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AggregateType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AppointmentState.php63
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AvailabilityProxyRequestType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeResponseType.php50
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemCreateOrDeleteOperationType.php46
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemTypeType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemUpdateOperationType.php67
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionLevelType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionReadAccessType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ClientAccessTokenTypeType.php76
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConferenceType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConflictResolutionType.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionFailureCauseType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionStatusType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContactSourceType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentComparisonType.php92
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentModeType.php64
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationActionTypeType.php96
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationNodeSortOrder.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationQueryTraversalType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CreateActionType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DateTimePrecisionType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekIndexType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekType.php106
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DaysOfWeekType.php21
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DefaultShapeNamesType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DelegateFolderPermissionLevelType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DeliverMeetingRequestsType.php57
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DictionaryURIType.php106
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisableReasonType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisposalType.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedFolderIdNameType.php394
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedPropertySetType.php106
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedUserType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ElcFolderType.php187
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/EmailAddressKeyType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExceptionPropertyURIType.php97
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExchangeVersionType.php98
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExternalAudience.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FileAsMappingType.php178
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlagStatusType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlaggedForActionType.php116
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FolderQueryTraversalType.php46
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FreeBusyViewType.php98
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldActionType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldStatusType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IdFormatType.php76
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImAddressKeyType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImportanceChoicesType.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IndexBasePointType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/InvalidRecipientResponseCodeType.php65
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemClassType.php291
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemQueryTraversalType.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LegacyFreeBusyType.php71
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LocationSourceType.php71
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailTipTypes.php107
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxSearchLocationType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxTypeType.php79
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MapiPropertyTypeType.php273
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingAttendeeType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingRequestTypeType.php84
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MemberStatusType.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageDispositionType.php66
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingDeliveryStatusType.php63
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingEventDescriptionType.php254
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingReportTemplateType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MonthNamesType.php124
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/NotificationEventTypeType.php79
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Occurrence.php96
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/OofState.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionActionType.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionLevelType.php116
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionReadAccessType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneCallStateType.php88
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneNumberKeyType.php187
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressIndexType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressKeyType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PreviewItemBaseShapeType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderActionType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderGroup.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResolveNamesSearchScopeType.php55
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseClassType.php63
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseCodeType.php4866
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseTypeType.php70
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RetentionActionType.php79
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RoutingType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleFieldURIType.php826
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleValidationErrorCodeType.php233
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Scope.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchFolderTraversalType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchItemKindType.php124
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchPageDirectionType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchResultType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SensitivityChoicesType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ServiceConfigurationType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SharingDataType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SortDirectionType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/StandardGroupByType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SubscriptionStatusType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SuggestionQuality.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SyncFolderItemsScopeType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskDelegateStateType.php76
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskStatusType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TransitionTargetKindType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UnindexedFieldURIType.php2941
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationDictionaryObjectTypesType.php106
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationPropertyType.php62
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoSizeType.php115
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoTypeType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ViewFilterType.php106
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDelegateType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDistributionGroupToImListType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImContactToGroup.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImGroupType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewImContactToGroup.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewTelUriContactToGroupType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ApplyConversationActionType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ArchiveItemType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseDelegateType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyFolderType.php32
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyItemType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseRequestType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ConvertIdType.php40
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyFolderType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateAttachmentType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderPathType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderType.php32
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateItemType.php65
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateManagedFolderRequestType.php32
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateUserConfigurationType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteAttachmentType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteFolderType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteItemType.php84
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteUserConfigurationType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisableAppType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisconnectPhoneCallType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/EmptyFolderType.php49
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExpandDLType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExportItemsType.php24
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindConversationType.php113
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindFolderType.php81
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindItemType.php149
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMailboxStatisticsByKeywordsType.php118
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMessageTrackingReportRequestType.php141
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindPeopleType.php113
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppManifestsType.php100
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppMarketplaceUrl.php16
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAttachmentType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetClientAccessTokenType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetConversationItemsType.php79
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDelegateType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDiscoverySearchConfigurationType.php42
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetEventsType.php39
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetFolderType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetHoldOnMailboxesType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemListType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemsType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetInboxRulesRequestType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetItemType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMailTipsType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMessageTrackingReportRequestType.php96
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemDetailsType.php62
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemStatisticsType.php32
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPasswordExpirationDateType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPersonaType.php67
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPhoneCallInformationType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRemindersType.php58
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomListsType.php17
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomsType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSearchableMailboxesType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServerTimeZonesType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServiceConfigurationType.php44
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingFolderType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingMetadataType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetStreamingEventsType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserAvailabilityRequestType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserConfigurationType.php38
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserOofSettingsRequest.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserPhotoType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserRetentionPolicyTagsType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/InstallAppType.php67
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAllItemsAsRead.php42
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAsJunkType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveFolderType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PerformReminderActionType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PlayOnPhoneType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RefreshSharingFolderType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveContactFromImListType.php24
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDelegateType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDistributionGroupFromImListType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImContactFromGroupType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImGroupType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ResolveNamesType.php82
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SearchMailboxesType.php104
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SendItemType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetHoldOnMailboxesType.php98
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetImGroupType.php32
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetUserOofSettingsRequest.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SubscribeType.php41
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderHierarchyType.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderItemsType.php88
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UninstallAppType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UnsubscribeType.php23
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateDelegateType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateFolderType.php24
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateInboxRulesRequestType.php42
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateItemType.php93
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateUserConfigurationType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UploadItemsType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDelegateResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDistributionGroupToImListResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImContactToGroupResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImGroupResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewImContactToGroupResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewTelUriContactToGroupResponse.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseMessageType.php19
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ArchiveItemResponse.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AttachmentInfoResponseMessageType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseDelegateResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseResponseMessageType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateAttachmentResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderPathResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateManagedFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateUserConfigurationResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DelegateUserResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteUserConfigurationResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisableAppResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisconnectPhoneCallResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/EmptyFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseMessageType.php76
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseMessageType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindConversationResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseMessageType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMessageTrackingReportResponseMessageType.php62
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindPeopleResponseMessageType.php60
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FolderInfoResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppManifestsResponseType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppMarketplaceUrlResponseMessageType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAttachmentResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDelegateResponseMessageType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDiscoverySearchConfigurationResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetHoldOnMailboxesResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemListResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemsResponse.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetInboxRulesResponseType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMailTipsResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMessageTrackingReportResponseMessageType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemDetailsResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemStatisticsResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPasswordExpirationDateResponseMessageType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPersonaResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPhoneCallInformationResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRemindersResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomListsResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomsResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSearchableMailboxesResponseMessageType.php32
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServiceConfigurationResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingFolderResponseMessageType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingMetadataResponseMessageType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseMessageType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserAvailabilityResponseType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserOofSettingsResponse.php46
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseMessageType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserRetentionPolicyTagsResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/InstallAppResponseType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ItemInfoResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MailTipsResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAllItemsAsReadResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PerformReminderActionResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PlayOnPhoneResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RefreshSharingFolderResponseMessageType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveContactFromImListResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDelegateResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDistributionGroupFromImListResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImContactFromGroupResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImGroupResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResponseMessageType.php70
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseMessageType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ServiceConfigurationResponseMessageType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetHoldOnMailboxesResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetImGroupResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetUserOofSettingsResponse.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseMessageType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseMessageType.php48
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseMessageType.php48
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UninstallAppResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UnsubscribeResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateDelegateResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateFolderResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateInboxRulesResponseType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateUserConfigurationResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseMessageType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteDateTransitionType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteMonthlyRecurrencePatternType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteYearlyRecurrencePatternType.php38
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptSharingInvitationType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AddressListIdType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AggregateOnType.php60
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdBaseType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdType.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderIdType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderItemIdType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AndType.php20
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppMetadata.php163
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToFolderFieldType.php60
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToItemFieldType.php105
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentIdType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentResponseShapeType.php65
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentType.php96
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeConflictData.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeType.php49
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseEmailAddressType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderIdType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderType.php103
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseGroupByType.php28
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseItemIdType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseNotificationEventType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseObjectChangedEventType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePagingType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePathToElementType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePermissionType.php92
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseSubscriptionRequestType.php65
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentAttributedValueType.php38
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEvent.php66
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEventDetails.php90
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarFolderType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarItemType.php447
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionSetType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarViewType.php55
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CancelCalendarItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ChangeDescriptionType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenRequestType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenType.php54
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CompleteNameType.php108
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConflictResultsType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConnectingSIDType.php67
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConstantValueType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactItemType.php413
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsFolderType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsViewType.php51
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContainsExpressionType.php46
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContextPropertyType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationActionType.php131
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationNodeType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationResponseType.php54
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationShape.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationType.php310
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CreateRuleOperationType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRecurrencePatternType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRegeneratingPatternType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeclineItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegatePermissionsType.php82
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegateUserType.php55
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteFolderFieldType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteItemFieldType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteRuleOperationType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeletedOccurrenceInfoType.php28
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DirectoryEntryType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DiscoverySearchConfigurationType.php73
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedFolderIdType.php51
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedGroupByType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistributionListType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Duration.php38
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EffectiveRightsType.php86
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressAttributedValueType.php35
-rwxr-xr-xmodules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryEntryType.php76
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressType.php64
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EncryptedSharedFolderDataType.php40
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EndDateRecurrenceRangeType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExchangeImpersonationType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesValueType.php40
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExistsType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedAttributeType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyAttributedValueType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FailedSearchMailboxType.php52
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldOrderType.php55
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldURIOrConstantType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FileAttachmentType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindFolderParentType.php77
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindItemParentType.php88
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindMessageTrackingSearchResultType.php103
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeDescriptionType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderIdType.php39
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderResponseShapeType.php39
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderType.php32
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ForwardItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FractionalPageViewType.php41
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyResponseType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyView.php57
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyViewOptionsType.php46
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupAttendeeConflictData.php64
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupByType.php51
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupedItemsType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryEntryType.php39
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImGroupType.php74
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImItemListType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndexedPageViewType.php48
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndividualAttendeeConflictData.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InstalledAppType.php173
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InternetHeaderType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IntervalRecurrencePatternBaseType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InvalidRecipientType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsEqualToType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanOrEqualToType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanOrEqualToType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsNotEqualToType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemAttachmentType.php104
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeDescriptionType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeType.php66
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemIdType.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemResponseShapeType.php77
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemType.php443
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/KeywordStatisticsSearchResultType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTips.php120
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTipsServiceConfiguration.php85
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxData.php49
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldResultType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldStatusType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxQueryType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxSearchScopeType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxStatisticsSearchResultType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ManagedFolderInformationType.php108
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingCancellationMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingMessageType.php94
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingRequestMessageType.php423
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingResponseMessageType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MemberType.php51
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MembersListType.php28
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageTrackingReportType.php82
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageType.php148
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MimeContentType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ModifiedEventType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MonthlyRegeneratingPatternType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MovedCopiedEventType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MultipleOperandBooleanExpressionType.php143
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NoEndRecurrenceRangeType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailResultType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailType.php102
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemStatisticType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotificationType.php120
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NumberedRecurrenceRangeType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceInfoType.php62
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceItemIdType.php50
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrencesRangeType.php57
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OpenAsAdminOrSystemServiceType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OrType.php20
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OutOfOfficeMailTip.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToExtendedFieldType.php134
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToIndexedFieldType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToUnindexedFieldType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PeriodType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionSetType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaAttributionType.php85
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPhoneNumberType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPostalAddressType.php158
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaResponseShapeType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaType.php972
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallIdType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallInformationType.php64
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberAttributedValueType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryEntryType.php39
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryEntryType.php75
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostItemType.php99
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemBaseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostalAddressAttributedValueType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemMailboxType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemResponseShapeType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PrivateCatalogAddInsType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProposeNewTimeType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleActionType.php40
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleAndType.php65
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleArgumentType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleConditionType.php69
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleRecipientIsType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleSenderDepartmentsType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleType.php69
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRulesServiceConfiguration.php50
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PullSubscriptionRequestType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PushSubscriptionRequestType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/QueryStringType.php56
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecipientTrackingEventType.php130
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrencePatternBaseType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceRangeBaseType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceType.php113
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDateTransitionType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDayTransitionType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdRanges.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdType.php41
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringTimeTransitionType.php33
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReferenceItemResponseType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RegeneratingPatternBaseType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeMonthlyRecurrencePatternType.php38
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeYearlyRecurrencePatternType.php48
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderItemActionType.php49
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderType.php105
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RemoveItemType.php19
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyAllToItemType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyBody.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyToItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestAttachmentIdType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestServerVersion.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResolutionType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectCoreType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RestrictionType.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RetentionPolicyTagType.php101
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RoomType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RootItemIdType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleActionsType.php140
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationErrorType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationType.php13
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateDateRangeType.php41
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateSizeRangeType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicatesType.php369
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleType.php100
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleValidationErrorType.php58
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchExpressionType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchFolderType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchMailboxesResultType.php117
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchParametersType.php47
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchPreviewItemType.php221
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchableMailboxType.php81
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SeekToConditionPageViewType.php53
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SendNotificationResultType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZone.php54
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZoneTime.php97
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializedSecurityContextType.php54
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServerVersionInfo.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServiceConfiguration.php19
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetFolderFieldType.php60
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetItemFieldType.php114
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetRuleOperationType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SidAndAttributesType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SingleRecipientType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseBaseType.php122
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomain.php39
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomainList.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StreamingSubscriptionRequest.php48
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringArrayAttributedValueType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringAttributedValueType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringType.php23
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Suggestion.php58
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionDayResult.php48
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsResponseType.php35
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsViewOptionsType.php100
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuppressReadReceiptType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyChangesType.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyCreateOrUpdateType.php61
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyDeleteType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsChangesType.php57
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsCreateOrUpdateType.php115
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsDeleteType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsReadFlagType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TargetFolderIdType.php43
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskRecurrenceType.php57
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskType.php243
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TasksFolderType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TentativelyAcceptItemType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeChangeType.php71
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneContextType.php27
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneDefinitionType.php62
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneType.php54
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TooBigGroupAttendeeConflictData.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TrackingPropertyType.php37
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionTargetType.php28
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionType.php28
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TwoOperandExpressionType.php24
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnifiedMessageServiceConfiguration.php48
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnknownAttendeeConflictData.php17
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UploadItemType.php73
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryEntryType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryObjectType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryType.php25
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationNameType.php26
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationType.php68
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserIdType.php67
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserMailboxType.php34
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserOofSettings.php71
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRecurrencePatternType.php36
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRegeneratingPatternType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WellKnownResponseObjectType.php18
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingHours.php42
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingPeriod.php45
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/YearlyRegeneratingPatternType.php16
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/messages.xsd4523
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/services.wsdl3624
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/types.xsd9779
-rw-r--r--modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php226
-rw-r--r--modules-available/locationinfo/frontend/frontendscript.js4
-rw-r--r--modules-available/locationinfo/hooks/runmode/config.json3
-rw-r--r--modules-available/locationinfo/inc/coursebackend.inc.php7
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php22
-rwxr-xr-xmodules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php242
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php147
-rwxr-xr-xmodules-available/locationinfo/inc/coursebackend/exchange.todo203
-rw-r--r--modules-available/locationinfo/inc/infopanel.inc.php9
-rw-r--r--modules-available/locationinfo/inc/locationinfo.inc.php23
-rw-r--r--modules-available/locationinfo/inc/splittime.php.txt80
-rw-r--r--modules-available/locationinfo/lang/de/backend-exchange.json14
-rw-r--r--modules-available/locationinfo/lang/de/permissions.json8
-rw-r--r--modules-available/locationinfo/lang/de/template-tags.json10
-rw-r--r--modules-available/locationinfo/lang/en/backend-exchange.json14
-rw-r--r--modules-available/locationinfo/lang/en/permissions.json8
-rw-r--r--modules-available/locationinfo/lang/en/template-tags.json10
-rw-r--r--modules-available/locationinfo/page.inc.php166
-rw-r--r--modules-available/locationinfo/permissions/permissions.json20
-rw-r--r--modules-available/locationinfo/style.css10
-rw-r--r--modules-available/locationinfo/templates/ajax-config-location.html14
-rw-r--r--modules-available/locationinfo/templates/ajax-config-server.html10
-rwxr-xr-xmodules-available/locationinfo/templates/frontend-default.html93
-rw-r--r--modules-available/locationinfo/templates/frontend-summary.html245
-rw-r--r--modules-available/locationinfo/templates/page-config-panel-default.html95
-rw-r--r--modules-available/locationinfo/templates/page-config-panel-summary.html71
-rw-r--r--modules-available/locationinfo/templates/page-config-panel-url.html25
-rw-r--r--modules-available/locationinfo/templates/page-locations.html14
-rw-r--r--modules-available/locationinfo/templates/page-panels.html55
-rw-r--r--modules-available/locationinfo/templates/page-servers.html103
-rw-r--r--modules-available/locationinfo/templates/page-tabs.html6
-rw-r--r--modules-available/locationinfo/templates/server-prop-bool.html6
-rw-r--r--modules-available/locationinfo/templates/server-prop-dropdown.html6
-rw-r--r--modules-available/locationinfo/templates/server-prop-generic.html6
-rw-r--r--modules-available/locations/config.json4
-rw-r--r--modules-available/locations/inc/location.inc.php4
-rw-r--r--modules-available/locations/lang/de/messages.json1
-rw-r--r--modules-available/locations/lang/de/permissions.json14
-rw-r--r--modules-available/locations/lang/de/template-tags.json5
-rw-r--r--modules-available/locations/lang/en/messages.json1
-rw-r--r--modules-available/locations/lang/en/permissions.json14
-rw-r--r--modules-available/locations/lang/en/template-tags.json5
-rw-r--r--modules-available/locations/page.inc.php328
-rw-r--r--modules-available/locations/permissions/permissions.json32
-rw-r--r--modules-available/locations/templates/location-subnets.html44
-rw-r--r--modules-available/locations/templates/locations.html50
-rw-r--r--modules-available/locations/templates/subnets.html8
-rw-r--r--modules-available/main/config.json3
-rw-r--r--modules-available/main/install.inc.php15
-rw-r--r--modules-available/main/lang/de/categories.json3
-rw-r--r--modules-available/main/lang/de/template-tags.json4
-rw-r--r--modules-available/main/lang/en/categories.json3
-rw-r--r--modules-available/main/page.inc.php5
-rw-r--r--modules-available/minilinux/config.json4
-rw-r--r--modules-available/minilinux/lang/de/permissions.json4
-rw-r--r--modules-available/minilinux/lang/de/template-tags.json5
-rw-r--r--modules-available/minilinux/lang/en/permissions.json4
-rw-r--r--modules-available/minilinux/lang/en/template-tags.json5
-rw-r--r--modules-available/minilinux/page.inc.php6
-rw-r--r--modules-available/minilinux/permissions/permissions.json8
-rw-r--r--modules-available/minilinux/templates/filelist.html6
-rw-r--r--modules-available/news/config.json8
-rw-r--r--modules-available/news/lang/de/permissions.json9
-rw-r--r--modules-available/news/lang/de/template-tags.json1
-rw-r--r--modules-available/news/lang/en/permissions.json9
-rw-r--r--modules-available/news/lang/en/template-tags.json1
-rw-r--r--modules-available/news/page.inc.php442
-rw-r--r--modules-available/news/permissions/permissions.json23
-rw-r--r--modules-available/news/templates/page-news.html20
-rw-r--r--modules-available/permissionmanager/api.inc.php7
-rw-r--r--modules-available/permissionmanager/clientscript.js45
-rw-r--r--modules-available/permissionmanager/config.json10
-rw-r--r--modules-available/permissionmanager/hooks/translation-global.inc.php38
-rw-r--r--modules-available/permissionmanager/inc/getpermissiondata.inc.php55
-rw-r--r--modules-available/permissionmanager/inc/permissiondbupdate.inc.php110
-rw-r--r--modules-available/permissionmanager/inc/permissionutil.inc.php225
-rw-r--r--modules-available/permissionmanager/install.inc.php137
-rw-r--r--modules-available/permissionmanager/lang/de/permissions.json7
-rw-r--r--modules-available/permissionmanager/lang/de/template-tags.json36
-rw-r--r--modules-available/permissionmanager/lang/en/permissions.json7
-rw-r--r--modules-available/permissionmanager/lang/en/template-tags.json36
-rw-r--r--modules-available/permissionmanager/page.inc.php218
-rw-r--r--modules-available/permissionmanager/permissions/permissions.json17
-rw-r--r--modules-available/permissionmanager/style.css85
-rw-r--r--modules-available/permissionmanager/templates/_page.html29
-rw-r--r--modules-available/permissionmanager/templates/header-menu.html25
-rw-r--r--modules-available/permissionmanager/templates/locationstable.html56
-rw-r--r--modules-available/permissionmanager/templates/page-permission-denied.html21
-rw-r--r--modules-available/permissionmanager/templates/role-filter-selectize.html6
-rw-r--r--modules-available/permissionmanager/templates/roleeditor.html96
-rw-r--r--modules-available/permissionmanager/templates/rolestable.html45
-rw-r--r--modules-available/permissionmanager/templates/treenode.html23
-rw-r--r--modules-available/permissionmanager/templates/treepanel.html4
-rw-r--r--modules-available/permissionmanager/templates/userstable.html40
-rw-r--r--modules-available/rebootcontrol/config.json9
-rw-r--r--modules-available/rebootcontrol/inc/rebootcontrol.inc.php65
-rw-r--r--modules-available/rebootcontrol/inc/rebootqueries.inc.php4
-rw-r--r--modules-available/rebootcontrol/lang/de/module.json1
-rw-r--r--modules-available/rebootcontrol/lang/de/permissions.json5
-rw-r--r--modules-available/rebootcontrol/lang/de/template-tags.json11
-rw-r--r--modules-available/rebootcontrol/lang/en/module.json1
-rw-r--r--modules-available/rebootcontrol/lang/en/permissions.json5
-rw-r--r--modules-available/rebootcontrol/lang/en/template-tags.json11
-rw-r--r--modules-available/rebootcontrol/page.inc.php130
-rw-r--r--modules-available/rebootcontrol/permissions/permissions.json11
-rw-r--r--modules-available/rebootcontrol/style.css13
-rw-r--r--modules-available/rebootcontrol/templates/_page.html256
-rw-r--r--modules-available/rebootcontrol/templates/header.html79
-rw-r--r--modules-available/rebootcontrol/templates/status.html26
-rw-r--r--modules-available/rebootcontrol/templates/task-list.html33
-rw-r--r--modules-available/roomplanner/baseconfig/getconfig.inc.php21
-rw-r--r--modules-available/roomplanner/clientscript.js1
-rw-r--r--modules-available/roomplanner/config.json11
-rw-r--r--modules-available/roomplanner/hooks/runmode/config.json3
-rw-r--r--modules-available/roomplanner/inc/pvsgenerator.inc.php1
-rw-r--r--modules-available/roomplanner/js/grid.js139
-rw-r--r--modules-available/roomplanner/lang/de/module.json4
-rw-r--r--modules-available/roomplanner/lang/de/permissions.json3
-rw-r--r--modules-available/roomplanner/lang/en/module.json4
-rw-r--r--modules-available/roomplanner/lang/en/permissions.json3
-rw-r--r--modules-available/roomplanner/page.inc.php47
-rw-r--r--modules-available/roomplanner/permissions/permissions.json5
-rw-r--r--modules-available/roomplanner/style.css12
-rw-r--r--modules-available/roomplanner/templates/footer.html60
-rw-r--r--modules-available/roomplanner/templates/header.html49
-rw-r--r--modules-available/roomplanner/templates/item-selector.html314
-rw-r--r--modules-available/roomplanner/templates/main-roomplan.html18
-rw-r--r--modules-available/roomplanner/templates/page.html369
-rw-r--r--modules-available/runmode/baseconfig/getconfig.inc.php14
-rw-r--r--modules-available/runmode/config.json9
-rw-r--r--modules-available/runmode/inc/runmode.inc.php14
-rw-r--r--modules-available/runmode/lang/de/messages.json1
-rw-r--r--modules-available/runmode/lang/de/module.json4
-rw-r--r--modules-available/runmode/lang/de/permissions.json3
-rw-r--r--modules-available/runmode/lang/de/template-tags.json1
-rw-r--r--modules-available/runmode/lang/en/messages.json1
-rw-r--r--modules-available/runmode/lang/en/module.json4
-rw-r--r--modules-available/runmode/lang/en/permissions.json3
-rw-r--r--modules-available/runmode/lang/en/template-tags.json1
-rw-r--r--modules-available/runmode/page.inc.php286
-rw-r--r--modules-available/runmode/permissions/permissions.json5
-rw-r--r--modules-available/runmode/templates/machine-selector.html32
-rw-r--r--modules-available/runmode/templates/module-machine-list.html4
-rw-r--r--modules-available/serversetup-bwlp-ipxe/api.inc.php252
-rw-r--r--modules-available/serversetup-bwlp-ipxe/config.json8
-rw-r--r--modules-available/serversetup-bwlp-ipxe/hooks/bootup.inc.php11
-rw-r--r--modules-available/serversetup-bwlp-ipxe/hooks/ipxe-update.inc.php10
-rw-r--r--modules-available/serversetup-bwlp-ipxe/hooks/main-warning.inc.php (renamed from modules-available/serversetup-bwlp/hooks/main-warning.inc.php)0
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php258
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php453
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php142
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/localboot.inc.php15
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php177
-rw-r--r--modules-available/serversetup-bwlp-ipxe/inc/pxelinux.inc.php302
-rw-r--r--modules-available/serversetup-bwlp-ipxe/install.inc.php89
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/de/messages.json20
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/de/module.json19
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/de/permissions.json11
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json75
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/en/messages.json20
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/en/module.json19
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/en/permissions.json11
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json75
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/pt/messages.json (renamed from modules-available/serversetup-bwlp/lang/pt/messages.json)0
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/pt/module.json (renamed from modules-available/serversetup-bwlp/lang/en/module.json)0
-rw-r--r--modules-available/serversetup-bwlp-ipxe/lang/pt/template-tags.json (renamed from modules-available/serversetup-bwlp/lang/pt/template-tags.json)0
-rw-r--r--modules-available/serversetup-bwlp-ipxe/page.inc.php829
-rw-r--r--modules-available/serversetup-bwlp-ipxe/permissions/permissions.json29
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/bootentry-list.html83
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/download.html53
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/heading.html3
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/ipaddress.html44
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html165
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/ipxe_update.html54
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/localboot.html59
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/menu-assign-location.html69
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html368
-rw-r--r--modules-available/serversetup-bwlp-ipxe/templates/menu-list.html100
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/config.json3
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/hooks/ipxe-update.inc.php9
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/hooks/main-warning.inc.php6
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/inc/ipxe.inc.php224
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/de/messages.json (renamed from modules-available/serversetup-bwlp/lang/de/messages.json)0
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/de/module.json (renamed from modules-available/serversetup-bwlp/lang/de/module.json)0
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/de/permissions.json6
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/de/template-tags.json (renamed from modules-available/serversetup-bwlp/lang/de/template-tags.json)6
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/en/messages.json (renamed from modules-available/serversetup-bwlp/lang/en/messages.json)0
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/en/module.json (renamed from modules-available/serversetup-bwlp/lang/pt/module.json)0
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/en/permissions.json6
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/en/template-tags.json (renamed from modules-available/serversetup-bwlp/lang/en/template-tags.json)6
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/pt/messages.json3
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/pt/module.json3
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/lang/pt/template-tags.json38
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/page.inc.php (renamed from modules-available/serversetup-bwlp/page.inc.php)44
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/permissions/permissions.json14
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/templates/heading.html (renamed from modules-available/serversetup-bwlp/templates/heading.html)0
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/templates/ipaddress.html (renamed from modules-available/serversetup-bwlp/templates/ipaddress.html)7
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/templates/ipxe.html (renamed from modules-available/serversetup-bwlp/templates/ipxe.html)18
-rw-r--r--modules-available/serversetup-bwlp-pxelinux/templates/ipxe_update.html38
-rw-r--r--modules-available/serversetup-bwlp/config.json3
-rw-r--r--modules-available/serversetup-bwlp/inc/ipxe.inc.php102
-rw-r--r--modules-available/serversetup-bwlp/lang/de/permissions.json5
-rw-r--r--modules-available/serversetup-bwlp/lang/en/permissions.json5
-rw-r--r--modules-available/serversetup-bwlp/permissions/permissions.json5
-rw-r--r--modules-available/serversetup-bwlp/style.css12
-rw-r--r--modules-available/serversetup-bwlp/templates/ipxe_update.html20
-rw-r--r--modules-available/session/config.json3
-rw-r--r--modules-available/statistics/api.inc.php137
-rw-r--r--modules-available/statistics/config.json12
-rw-r--r--modules-available/statistics/hooks/cron.inc.php32
-rw-r--r--modules-available/statistics/inc/filter.inc.php49
-rw-r--r--modules-available/statistics/inc/filterset.inc.php82
-rw-r--r--modules-available/statistics/inc/parser.inc.php36
-rw-r--r--modules-available/statistics/inc/statistics.inc.php17
-rw-r--r--modules-available/statistics/install.inc.php17
-rw-r--r--modules-available/statistics/lang/de/permissions.json13
-rw-r--r--modules-available/statistics/lang/de/template-tags.json4
-rw-r--r--modules-available/statistics/lang/en/permissions.json13
-rw-r--r--modules-available/statistics/lang/en/template-tags.json4
-rw-r--r--modules-available/statistics/page.inc.php267
-rw-r--r--modules-available/statistics/pages/projectors.inc.php4
-rw-r--r--modules-available/statistics/permissions/permissions.json31
-rw-r--r--modules-available/statistics/style.css32
-rw-r--r--modules-available/statistics/templates/clientlist.html25
-rw-r--r--modules-available/statistics/templates/cpumodels.html4
-rw-r--r--modules-available/statistics/templates/filterbox.html17
-rw-r--r--modules-available/statistics/templates/id44.html2
-rw-r--r--modules-available/statistics/templates/kvmstate.html2
-rw-r--r--modules-available/statistics/templates/machine-hdds.html6
-rw-r--r--modules-available/statistics/templates/machine-main.html44
-rw-r--r--modules-available/statistics/templates/machine-notes.html7
-rw-r--r--modules-available/statistics/templates/memory.html2
-rw-r--r--modules-available/statistics/templates/summary.html4
-rw-r--r--modules-available/statistics_reporting/config.json9
-rw-r--r--modules-available/statistics_reporting/inc/queries.inc.php12
-rw-r--r--modules-available/statistics_reporting/lang/de/template-tags.json2
-rw-r--r--modules-available/statistics_reporting/lang/en/template-tags.json2
-rw-r--r--modules-available/statistics_reporting/lang/pt/template-tags.json3
-rw-r--r--modules-available/statistics_reporting/page.inc.php4
-rw-r--r--modules-available/statistics_reporting/permissions/permissions.json36
-rw-r--r--modules-available/summernote/config.json17
-rw-r--r--modules-available/support/config.json4
-rw-r--r--modules-available/sysconfig/addmodule_adauth.inc.php25
-rw-r--r--modules-available/sysconfig/addmodule_custommodule.inc.php4
-rw-r--r--modules-available/sysconfig/addmodule_ldapauth.inc.php24
-rw-r--r--modules-available/sysconfig/api.inc.php8
-rw-r--r--modules-available/sysconfig/config.json4
-rw-r--r--modules-available/sysconfig/inc/configmodule.inc.php2
-rw-r--r--modules-available/sysconfig/inc/configmodule/adauth.inc.php2
-rw-r--r--modules-available/sysconfig/inc/configmodule/ldapauth.inc.php2
-rw-r--r--modules-available/sysconfig/inc/configmodulebaseldap.inc.php6
-rw-r--r--modules-available/sysconfig/inc/configtgz.inc.php51
-rw-r--r--modules-available/sysconfig/lang/de/permissions.json8
-rw-r--r--modules-available/sysconfig/lang/de/template-tags.json10
-rw-r--r--modules-available/sysconfig/lang/en/permissions.json8
-rw-r--r--modules-available/sysconfig/lang/en/template-tags.json8
-rw-r--r--modules-available/sysconfig/page.inc.php44
-rw-r--r--modules-available/sysconfig/permissions/permissions.json20
-rw-r--r--modules-available/sysconfig/templates/ad-selfsearch.html2
-rw-r--r--modules-available/sysconfig/templates/ad-start.html10
-rw-r--r--modules-available/sysconfig/templates/ad_ldap-checkconnection.html2
-rw-r--r--modules-available/sysconfig/templates/ad_ldap-checkcredentials.html2
-rw-r--r--modules-available/sysconfig/templates/ad_ldap-homedir.html15
-rw-r--r--modules-available/sysconfig/templates/ldap-start.html10
-rw-r--r--modules-available/sysconfig/templates/list-configs.html21
-rw-r--r--modules-available/sysconfig/templates/list-modules.html24
-rw-r--r--modules-available/sysconfig/templates/sshconfig-start.html2
-rw-r--r--modules-available/sysconfignew/config.json4
-rw-r--r--modules-available/syslog/api.inc.php39
-rw-r--r--modules-available/syslog/config.json8
-rw-r--r--modules-available/syslog/hooks/cron.inc.php21
-rw-r--r--modules-available/syslog/lang/de/messages.json4
-rw-r--r--modules-available/syslog/lang/de/permissions.json4
-rw-r--r--modules-available/syslog/lang/de/template-tags.json11
-rw-r--r--modules-available/syslog/lang/en/messages.json4
-rw-r--r--modules-available/syslog/lang/en/permissions.json4
-rw-r--r--modules-available/syslog/lang/en/template-tags.json11
-rw-r--r--modules-available/syslog/page.inc.php41
-rw-r--r--modules-available/syslog/permissions/permissions.json11
-rw-r--r--modules-available/syslog/templates/heading.html68
-rw-r--r--modules-available/syslog/templates/page-syslog.html1
-rw-r--r--modules-available/systemstatus/config.json8
-rw-r--r--modules-available/systemstatus/lang/de/permissions.json13
-rw-r--r--modules-available/systemstatus/lang/de/template-tags.json2
-rw-r--r--modules-available/systemstatus/lang/en/permissions.json13
-rw-r--r--modules-available/systemstatus/page.inc.php21
-rw-r--r--modules-available/systemstatus/permissions/permissions.json35
-rw-r--r--modules-available/systemstatus/templates/_page.html13
-rw-r--r--modules-available/translation/config.json4
-rw-r--r--modules-available/translation/page.inc.php75
-rw-r--r--modules-available/translation/templates/edit.html6
-rw-r--r--modules-available/usermanagement/config.json6
-rw-r--r--modules-available/vmstore/baseconfig/getconfig.inc.php6
-rw-r--r--modules-available/vmstore/config.json4
-rw-r--r--modules-available/vmstore/lang/de/permissions.json4
-rw-r--r--modules-available/vmstore/lang/de/template-tags.json6
-rw-r--r--modules-available/vmstore/lang/en/permissions.json4
-rw-r--r--modules-available/vmstore/lang/en/template-tags.json4
-rw-r--r--modules-available/vmstore/page.inc.php22
-rw-r--r--modules-available/vmstore/permissions/permissions.json10
-rw-r--r--modules-available/vmstore/templates/page-vmstore.html16
-rw-r--r--modules-available/webinterface/config.json4
-rw-r--r--modules-available/webinterface/lang/de/permissions.json7
-rw-r--r--modules-available/webinterface/lang/en/permissions.json7
-rw-r--r--modules-available/webinterface/page.inc.php22
-rw-r--r--modules-available/webinterface/permissions/permissions.json19
-rw-r--r--modules-available/webinterface/style.css7
-rw-r--r--modules-available/webinterface/templates/customization.html11
-rw-r--r--modules-available/webinterface/templates/heading.html20
-rw-r--r--modules-available/webinterface/templates/https.html102
-rw-r--r--modules-available/webinterface/templates/passwords.html23
1228 files changed, 81065 insertions, 4283 deletions
diff --git a/modules-available/adduser/config.json b/modules-available/adduser/config.json
index 2c63c085..110f8b67 100644
--- a/modules-available/adduser/config.json
+++ b/modules-available/adduser/config.json
@@ -1,2 +1,3 @@
{
-}
+ "category": "main.content"
+} \ No newline at end of file
diff --git a/modules-available/adduser/lang/de/messages.json b/modules-available/adduser/lang/de/messages.json
index 4f62dcbf..a744ae5f 100644
--- a/modules-available/adduser/lang/de/messages.json
+++ b/modules-available/adduser/lang/de/messages.json
@@ -1,5 +1,11 @@
{
+ "adduser-success": "Benutzer erfolgreich hinzugef\u00fcgt",
+ "cannot-delete-1-self": "Sie k\u00f6nnen nicht den Benutzer mit der ID 1 oder sich selbst l\u00f6schen",
+ "db-error": "Datenbankfehler: {{0}}",
+ "password-changed": "Passwort ge\u00e4ndert",
"password-mismatch": "Passwort und Passwortbest\u00e4tigung stimmen nicht \u00fcberein",
- "adduser-disabled": "Keine ausreichenden Rechte, um weitere Benutzer hinzuzuf\u00fcgen",
- "adduser-success": "Benutzer erfolgreich hinzugef\u00fcgt"
+ "roles-updated": "Rollen aktualisiert",
+ "user-deleted": "Benutzer {{0}} (ID={1}}) gel\u00f6scht",
+ "user-edited": "Benutzerdaten wurden ge\u00e4ndert",
+ "user-not-found": "Benutzer mit ID {{0}} nicht gefunden"
} \ No newline at end of file
diff --git a/modules-available/adduser/lang/de/module.json b/modules-available/adduser/lang/de/module.json
new file mode 100644
index 00000000..e4c785b5
--- /dev/null
+++ b/modules-available/adduser/lang/de/module.json
@@ -0,0 +1,3 @@
+{
+ "module_name": "Nutzerverwaltung"
+} \ No newline at end of file
diff --git a/modules-available/adduser/lang/de/permissions.json b/modules-available/adduser/lang/de/permissions.json
new file mode 100644
index 00000000..8792ac14
--- /dev/null
+++ b/modules-available/adduser/lang/de/permissions.json
@@ -0,0 +1,6 @@
+{
+ "user.add": "Neuen Nutzer hinzuf\u00fcgen",
+ "user.edit": "Nutzer bearbeiten",
+ "user.remove": "Nutzer l\u00f6schen",
+ "user.view-list": "Nutzerliste anzeigen"
+} \ No newline at end of file
diff --git a/modules-available/adduser/lang/de/template-tags.json b/modules-available/adduser/lang/de/template-tags.json
index 99d17947..419d0e1a 100644
--- a/modules-available/adduser/lang/de/template-tags.json
+++ b/modules-available/adduser/lang/de/template-tags.json
@@ -1,6 +1,25 @@
{
+ "lang_addUser": "Nutzer hinzuf\u00fcgen",
+ "lang_assignRoles": "Rollen zuweisen",
+ "lang_changeLoginHint": "Sie k\u00f6nnen den Namen, den der Nutzer beim Login angeben muss, \u00e4ndern. Dies ist nur bei lokalen Nutzern m\u00f6glich, die nicht \u00fcber LDAP\/AD authentifiziert werden.",
+ "lang_changeOwnPasswordHint": "Ihr eigenes Passwort k\u00f6nnen Sie \u00fcber den Button \"Passwort \u00e4ndern\" im Men\u00fc \u00e4ndern.",
+ "lang_changePassword": "Neues Passwort",
+ "lang_confirmDelete": "L\u00f6schen best\u00e4tigen",
"lang_confirmation": "Wiederholen",
"lang_createUser": "Benutzer anlegen",
+ "lang_editUser": "Benutzer bearbeiten",
+ "lang_email": "E-Mail",
"lang_fullName": "Vollst\u00e4ndiger Name",
- "lang_telephone": "Telefon"
-}
+ "lang_fullnameMissing": "Kein Name angegeben",
+ "lang_login": "Login",
+ "lang_loginTooShort": "Login zu kurz",
+ "lang_name": "Name",
+ "lang_passwordTooShort": "Passwort zu kurz",
+ "lang_passwordsDontMatch": "Passworte stimmen nicht \u00fcberein",
+ "lang_phone": "Telefon",
+ "lang_role": "Rolle",
+ "lang_userDeleteConfirm": "M\u00f6chten Sie diesen Benutzer wirklich l\u00f6schen?",
+ "lang_userIdCol": "ID",
+ "lang_userManagement": "Benutzerverwaltung",
+ "lang_userlist": "Benutzerliste"
+} \ No newline at end of file
diff --git a/modules-available/adduser/lang/en/messages.json b/modules-available/adduser/lang/en/messages.json
index 3a402278..67bca6f9 100644
--- a/modules-available/adduser/lang/en/messages.json
+++ b/modules-available/adduser/lang/en/messages.json
@@ -1,5 +1,11 @@
{
+ "adduser-success": "User successfully added",
+ "cannot-delete-1-self": "Cannot delete user with ID 1 or yourself",
+ "db-error": "Database error: {{0}}",
+ "password-changed": "Password changed",
"password-mismatch": "Password and password confirmation do not match",
- "adduser-disabled": "Insufficient privileges to add more users",
- "adduser-success": "User successfully added"
+ "roles-updated": "Roles have been updated",
+ "user-deleted": "Deleted user {{0}} (ID={{1}})",
+ "user-edited": "User data has been updated",
+ "user-not-found": "User with ID {{0}} not found"
} \ No newline at end of file
diff --git a/modules-available/adduser/lang/en/module.json b/modules-available/adduser/lang/en/module.json
new file mode 100644
index 00000000..f376db34
--- /dev/null
+++ b/modules-available/adduser/lang/en/module.json
@@ -0,0 +1,3 @@
+{
+ "module_name": "User management"
+} \ No newline at end of file
diff --git a/modules-available/adduser/lang/en/permissions.json b/modules-available/adduser/lang/en/permissions.json
new file mode 100644
index 00000000..ed3d8ee3
--- /dev/null
+++ b/modules-available/adduser/lang/en/permissions.json
@@ -0,0 +1,6 @@
+{
+ "user.add": "Add new user",
+ "user.edit": "Edit user",
+ "user.remove": "Remove user",
+ "user.view-list": "Show userlist"
+} \ No newline at end of file
diff --git a/modules-available/adduser/lang/en/template-tags.json b/modules-available/adduser/lang/en/template-tags.json
index 24f8cd42..d927964e 100644
--- a/modules-available/adduser/lang/en/template-tags.json
+++ b/modules-available/adduser/lang/en/template-tags.json
@@ -1,6 +1,25 @@
{
+ "lang_addUser": "Add user",
+ "lang_assignRoles": "Assign roles",
+ "lang_changeLoginHint": "You can change the login identifier used for logging in. This is only enabled for local acounts that are not linked to LDAP\/AD servers.",
+ "lang_changeOwnPasswordHint": "You can change your own password by clicking the \"change password\" button in the menu.",
+ "lang_changePassword": "Change password",
+ "lang_confirmDelete": "Confirm delete",
"lang_confirmation": "Confirm Password",
"lang_createUser": "Create User",
+ "lang_editUser": "Edit user",
+ "lang_email": "Email",
"lang_fullName": "Full Name",
- "lang_telephone": "Telephone"
+ "lang_fullnameMissing": "Full name missing",
+ "lang_login": "Login",
+ "lang_loginTooShort": "Login too short",
+ "lang_name": "Name",
+ "lang_passwordTooShort": "Password too short",
+ "lang_passwordsDontMatch": "Passwords do not match",
+ "lang_phone": "Phone",
+ "lang_role": "Role",
+ "lang_userDeleteConfirm": "Do you want to delete this user?",
+ "lang_userIdCol": "ID",
+ "lang_userManagement": "User management",
+ "lang_userlist": "User list"
}
diff --git a/modules-available/adduser/page.inc.php b/modules-available/adduser/page.inc.php
index 87aaeef1..cffe33f9 100644
--- a/modules-available/adduser/page.inc.php
+++ b/modules-available/adduser/page.inc.php
@@ -7,52 +7,220 @@ class Page_AddUser extends Page
{
User::load();
- if (isset($_POST['action']) && $_POST['action'] === 'adduser') {
- // Check required fields
- if (empty($_POST['user']) || empty($_POST['pass1']) || empty($_POST['pass2']) || empty($_POST['fullname'])) {
- Message::addError('main.empty-field');
- Util::redirect('?do=AddUser');
- } elseif ($_POST['pass1'] !== $_POST['pass2']) {
- Message::addError('password-mismatch');
- Util::redirect('?do=AddUser');
- } elseif (!User::hasPermission('superadmin') && Database::queryFirst('SELECT userid FROM user LIMIT 1') !== false) {
- Message::addError('adduser-disabled');
- Util::redirect('?do=Session&action=login');
+ $action = Request::post(('action'), false, 'string');
+
+ if ($action === 'adduser') {
+ $this->addUser();
+ } elseif ($action === 'edituser') {
+ $this->editUser();
+ } elseif ($action === 'deleteuser') {
+ $this->deleteUser();
+ }
+ if (Request::isPost()) {
+ Util::redirect('?do=adduser');
+ }
+ }
+
+ private function addUser()
+ {
+ // Check required fields
+ $login = Request::post('login', '', 'string');
+ $pass1 = Request::post('pass1', '', 'string');
+ $pass2 = Request::post('pass2', '', 'string');
+ $fullname = Request::post('fullname', '', 'string');
+ $phone = Request::post('phone', '', 'string');
+ $email = Request::post('email', '', 'string');
+ if (empty($login) || empty($pass1) || empty($pass2) || empty($fullname)) {
+ Message::addError('main.empty-field');
+ return;
+ } elseif ($pass1 !== $pass2) {
+ Message::addError('password-mismatch');
+ return;
+ } else {
+ if (Database::queryFirst('SELECT userid FROM user LIMIT 1') !== false) {
+ User::assertPermission('user.add');
+ }
+ $data = array(
+ 'login' => $login,
+ 'pass' => Crypto::hash6($pass1),
+ 'fullname' => $fullname,
+ 'phone' => $phone,
+ 'email' => $email,
+ );
+ Database::exec('INSERT INTO user SET login = :login, passwd = :pass, fullname = :fullname, phone = :phone, email = :email', $data);
+ $id = Database::lastInsertId();
+ // Make it superadmin if first user. This method sucks as it's a race condition but hey...
+ $ret = Database::queryFirst('SELECT Count(*) AS num FROM user');
+ if ($ret !== false && $ret['num'] == 1) {
+ $ret = Database::exec('UPDATE user SET permissions = 1, userid = 1 WHERE userid = :id', ['id' => $id], true);
+ if ($ret !== false) {
+ EventLog::clear();
+ }
+ // same for permissionmanager
+ Database::exec("INSERT INTO `role_x_user` (userid, roleid) VALUES (:id, 1)", ['id' => $id], true);
+ EventLog::info('Created first user ' . $login);
} else {
- $data = array(
- 'user' => $_POST['user'],
- 'pass' => Crypto::hash6($_POST['pass1']),
- 'fullname' => $_POST['fullname'],
- 'phone' => $_POST['phone'],
- 'email' => $_POST['email'],
- );
- if (Database::exec('INSERT INTO user SET login = :user, passwd = :pass, fullname = :fullname, phone = :phone, email = :email', $data) != 1) {
- Util::traceError('Could not create new user in DB');
+ EventLog::info(User::getName() . ' created user ' . $login);
+ }
+ Message::addInfo('adduser-success');
+ $this->saveRoles($id);
+ return;
+ }
+ }
+
+ private function editUser()
+ {
+ User::assertPermission('user.edit');
+ $userid = Request::post('userid', false, 'int');
+ if ($userid === false) {
+ Message::addError('main.parameter-missing', 'userid');
+ return;
+ }
+ $user = Database::queryFirst('SELECT userid, login, fullname, phone, email
+ FROM user WHERE userid = :userid', compact('userid'));
+ if ($user === false) {
+ Message::addError('user-not-found', $userid);
+ return;
+ }
+ // Check required fields
+ $login = Request::post('login', '', 'string');
+ $pass1 = Request::post('pass1', '', 'string');
+ $pass2 = Request::post('pass2', '', 'string');
+ $fullname = Request::post('fullname', '', 'string');
+ $phone = Request::post('phone', '', 'string');
+ $email = Request::post('email', '', 'string');
+ if (empty($login) || empty($fullname)) {
+ Message::addError('main.empty-field');
+ } elseif (!(empty($pass1) && empty($pass2)) && $pass1 !== $pass2) {
+ Message::addError('password-mismatch');
+ } else {
+ $data = array(
+ 'login' => $login,
+ 'fullname' => $fullname,
+ 'phone' => $phone,
+ 'email' => $email,
+ 'userid' => $userid,
+ );
+ $ret = Database::exec('UPDATE user SET login = :login, fullname = :fullname, phone = :phone, email = :email WHERE userid = :userid', $data, true);
+ if ($ret === false) {
+ Message::addError('db-error', Database::lastError());
+ } else {
+ if ($ret > 0) {
+ Message::addSuccess('user-edited');
}
- // Make it superadmin if first user. This method sucks as it's a race condition but hey...
- $ret = Database::queryFirst('SELECT Count(*) AS num FROM user');
- if ($ret !== false && $ret['num'] == 1) {
- Database::exec('UPDATE user SET permissions = 1');
- EventLog::clear();
- EventLog::info('Created first user ' . $_POST['user']);
- } else {
- EventLog::info(User::getName() . ' created user ' . $_POST['user']);
+ if (!empty($pass1) && $userid !== User::getId()) {
+ $data = [
+ 'pass' => Crypto::hash6($pass1),
+ 'userid' => $userid,
+ ];
+ Database::exec('UPDATE user SET passwd = :pass WHERE userid = :userid', $data);
+ Message::addSuccess('password-changed');
}
- Message::addInfo('adduser-success');
- Util::redirect('?do=Session&action=login');
+ $this->saveRoles($userid);
}
}
+ Util::redirect('?do=adduser&show=edituser&userid=' . $userid);
+ }
+
+ private function deleteUser()
+ {
+ User::assertPermission('user.remove');
+ $userid = Request::post('userid', false, 'int');
+ if ($userid === false) {
+ Message::addError('main.parameter-missing', 'userid');
+ return;
+ }
+ //\\
+ $user = Database::queryFirst('SELECT userid, login
+ FROM user WHERE userid = :userid', compact('userid'));
+ if ($user === false) {
+ Message::addError('user-not-found', $userid);
+ return;
+ }
+ if ($user['userid'] == 1 || $user['userid'] == User::getId()) {
+ Message::addError('cannot-delete-1-self');
+ return;
+ }
+ Database::exec('DELETE FROM user WHERE userid = :userid', compact('userid'));
+ Message::addSuccess('user-deleted', $user['login'], $userid);
+ }
+
+ private function saveRoles($userid)
+ {
+ if (!Module::isAvailable('permissionmanager'))
+ return;
+ if (!User::hasPermission('.permissionmanager.users.edit-roles'))
+ return;
+ $roles = Request::post('roles', [], 'array');
+ $ret = PermissionDbUpdate::setRolesForUser([$userid], $roles);
+ if ($ret > 0) {
+ Message::addSuccess('roles-updated');
+ }
}
protected function doRender()
{
- // No user was added, check if current user is allowed to add a new user
- // Currently you can only add users if there is no user yet. :)
- if (!User::hasPermission('superadmin') && Database::queryFirst('SELECT userid FROM user LIMIT 1') !== false) {
- Message::addError('adduser-disabled');
- } else {
- Render::addTemplate('page-adduser', $_POST);
+ Render::addTemplate('header');
+ $hasUsers = (Database::queryFirst('SELECT userid FROM user LIMIT 1') !== false);
+ $show = Request::get('show', ($hasUsers ? 'list' : 'adduser'), 'string');
+ if ($show === 'adduser') {
+ // Can add user if: - no user exists yet; - user has explicit permission to add users
+ if ($hasUsers) {
+ User::assertPermission('user.add');
+ }
+ Render::openTag('form', ['class' => 'form-adduser', 'action' => '?do=adduser', 'method' => 'post']);
+ Render::addTemplate('page-adduser');
+ Render::addTemplate('js-add-edit');
+ if ($hasUsers) {
+ $this->showRoles();
+ }
+ Render::closeTag('form');
+ } elseif ($show === 'edituser') {
+ User::assertPermission('user.edit');
+ $userid = Request::get('userid', false, 'int');
+ if ($userid === false) {
+ Message::addError('main.parameter-missing', 'userid');
+ Util::redirect('?do=adduser&show=list');
+ }
+ $user = Database::queryFirst('SELECT userid, login, fullname, phone, email
+ FROM user WHERE userid = :userid', compact('userid'));
+ if ($user === false) {
+ Message::addError('user-not-found', $userid);
+ } else {
+ $user['password_disabled'] = User::getId() === $userid ? 'disabled' : false;
+ // TODO: LDAP -> disallow pw change, maybe other fields too?
+ Render::openTag('form', ['class' => 'form-adduser', 'action' => '?do=adduser', 'method' => 'post']);
+ Render::addTemplate('page-edituser', $user);
+ Render::addTemplate('js-add-edit');
+ $this->showRoles($userid);
+ Render::closeTag('form');
+ }
+ } elseif ($show === 'list') {
+ User::assertPermission('user.view-list');
+ $page = new Paginate('SELECT userid, login, fullname, phone, email FROM user ORDER BY login', 50);
+ $data = ['list' => $page->exec()->fetchAll(PDO::FETCH_ASSOC)];
+ foreach ($data['list'] as &$u) {
+ // Don't allow deleting user 1 and self
+ $u['hide_delete'] = $u['userid'] == 1 || $u['userid'] == User::getId();
+ if ($u['userid'] == 1) {
+ $u['userClass'] = 'slx-bold';
+ }
+ }
+ unset($u);
+ Permission::addGlobalTags($data['perms'], null, ['user.add', 'user.edit', 'user.remove']);
+ Module::isAvailable('js_stupidtable');
+ $page->render('page-userlist', $data);
}
}
+ private function showRoles($userid = false)
+ {
+ if (!Module::isAvailable('permissionmanager'))
+ return;
+ if (!User::hasPermission('.permissionmanager.users.edit-roles'))
+ return;
+ $data = ['roles' => PermissionUtil::getRoles($userid, false)];
+ Render::addTemplate('user-permissions', $data);
+ }
+
}
diff --git a/modules-available/adduser/permissions/permissions.json b/modules-available/adduser/permissions/permissions.json
new file mode 100644
index 00000000..e8fd0a5e
--- /dev/null
+++ b/modules-available/adduser/permissions/permissions.json
@@ -0,0 +1,14 @@
+{
+ "user.add": {
+ "location-aware": false
+ },
+ "user.edit": {
+ "location-aware": false
+ },
+ "user.remove": {
+ "location-aware": false
+ },
+ "user.view-list": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/adduser/style.css b/modules-available/adduser/style.css
new file mode 100644
index 00000000..15f04b80
--- /dev/null
+++ b/modules-available/adduser/style.css
@@ -0,0 +1,19 @@
+.form-adduser {
+ max-width: 600px;
+ padding: 10px;
+ margin: 0 auto;
+}
+
+.form-adduser .form-control {
+ position: relative;
+ font-size: 16px;
+ height: auto;
+ padding: 10px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+#add-msg {
+ height: 1em;
+} \ No newline at end of file
diff --git a/modules-available/adduser/templates/header.html b/modules-available/adduser/templates/header.html
new file mode 100644
index 00000000..34011e29
--- /dev/null
+++ b/modules-available/adduser/templates/header.html
@@ -0,0 +1,3 @@
+<div class="page-header">
+ <h1>{{lang_userManagement}}</h1>
+</div> \ No newline at end of file
diff --git a/modules-available/adduser/templates/js-add-edit.html b/modules-available/adduser/templates/js-add-edit.html
new file mode 100644
index 00000000..db8d435a
--- /dev/null
+++ b/modules-available/adduser/templates/js-add-edit.html
@@ -0,0 +1,29 @@
+<script><!--
+document.addEventListener('DOMContentLoaded', function() {
+ var $login = $('#login');
+ var $pass1 = $('#pass1');
+ var $pass2 = $('#pass2');
+ var $fullname = $('#fullname');
+ var $msg = $('#add-msg');
+ var $btn = $('.save-btn');
+ if (typeof SLX_EDITUSER === 'undefined') {
+ SLX_EDITUSER = false;
+ }
+ var ev = function() {
+ var msg = '';
+ if ($login.val().length < 2) {
+ msg = '{{lang_loginTooShort}}';
+ } else if ($pass1.val() !== $pass2.val()) {
+ msg = '{{lang_passwordsDontMatch}}';
+ } else if ((!SLX_EDITUSER || $pass1.val().length > 0) && $pass1.val().length < 2) {
+ msg = '{{lang_passwordTooShort}}';
+ } else if ($fullname.val().length < 1) {
+ msg = '{{lang_fullnameMissing}}';
+ }
+ $msg.text(msg);
+ $btn.prop('disabled', !!msg);
+ };
+ $('.event-box').change(ev).keyup(ev);
+ if (SLX_EDITUSER) ev();
+});
+//--></script> \ No newline at end of file
diff --git a/modules-available/adduser/templates/page-adduser.html b/modules-available/adduser/templates/page-adduser.html
index deb911c0..08587373 100644
--- a/modules-available/adduser/templates/page-adduser.html
+++ b/modules-available/adduser/templates/page-adduser.html
@@ -1,28 +1,41 @@
-<form class="form-adduser" action="?do=AddUser" method="post">
- <input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="position:absolute;top:-2000px" tabindex="-1">
- <input type="password" name="password_fake" id="password_fake" value="" style="position:absolute;top:-2000px" tabindex="-1">
- <h2 class="form-signin-heading">{{lang_createUser}}</h2>
- <div class="row">
- <div class="col-md-4">{{lang_username}} *</div>
- <div class="col-md-4"><input type="text" name="user" value="{{user}}" class="form-control" placeholder="{{lang_username}}" autofocus></div>
+<input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="position:absolute;top:-2000px" tabindex="-1">
+<input type="password" name="password_fake" id="password_fake" value="" style="position:absolute;top:-2000px" tabindex="-1">
+<h2>{{lang_createUser}}</h2>
+<div class="row">
+ <div class="col-md-4"><label for="login">{{lang_login}} *</label></div>
+ <div class="col-md-4"><input id="login" type="text" name="login" value="{{login}}" class="form-control event-box" placeholder="{{lang_username}}" autofocus></div>
+</div>
+<br>
+<div class="row">
+ <div class="col-md-4"><label for="pass1">{{lang_password}} *</label></div>
+ <div class="col-md-4"><input id="pass1" type="password" name="pass1" class="form-control event-box" placeholder="{{lang_password}}"></div>
+ <div class="col-md-4"><input id="pass2" type="password" name="pass2" class="form-control event-box" placeholder="{{lang_confirmation}}"></div>
+</div>
+<br>
+<div class="row">
+ <div class="col-md-4"><label for="fullname">{{lang_fullName}} *</label></div>
+ <div class="col-md-4"><input id="fullname" type="text" name="fullname" value="{{fullname}}" class="form-control event-box" placeholder="{{lang_fullName}}"></div>
+</div>
+<br>
+<div class="row">
+ <div class="col-md-4"><label for="phone">{{lang_phone}}</label></div>
+ <div class="col-md-4"><input id=phone" type="text" name="phone" value="{{phone}}" class="form-control" placeholder="{{lang_phone}}"></div>
+</div>
+<br>
+<div class="row">
+ <div class="col-md-4"><label for="email">{{lang_email}}</label></div>
+ <div class="col-md-4"><input id="email" type="text" name="email" value="{{email}}" class="form-control" placeholder="{{lang_email}}"></div>
+</div>
+<br>
+<div class="row">
+ <div class="col-md-4"></div>
+ <div class="col-md-8">
+ <button class="btn btn-lg btn-primary btn-block save-btn" type="submit" disabled>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_createUser}}
+ </button>
+ <div id="add-msg" class="text-danger slx-bold"></div>
</div>
- <div class="row">
- <div class="col-md-4">{{lang_password}} *</div>
- <div class="col-md-4"><input type="password" name="pass1" class="form-control" placeholder="{{lang_password}}"></div>
- <div class="col-md-4"><input type="password" name="pass2" class="form-control" placeholder="{{lang_confirmation}}"></div>
- </div>
- <div class="row">
- <div class="col-md-4">{{lang_fullName}} *</div>
- <div class="col-md-4"><input type="text" name="fullname" value="{{fullname}}" class="form-control" placeholder="{{lang_fullName}}"></div>
- </div>
- <div class="row">
- <div class="col-md-4">{{lang_telephone}}</div>
- <div class="col-md-4"><input type="text" name="phone" value="{{phone}}" class="form-control" placeholder="{{lang_telephone}}"></div>
- </div>
- <div class="row">
- <div class="col-md-4">E-Mail</div>
- <div class="col-md-4"><input type="text" name="email" value="{{email}}" class="form-control" placeholder="E-Mail"></div>
- </div>
- <button class="btn btn-lg btn-primary btn-block" type="submit">{{lang_createUser}}</button>
- <input type="hidden" name="action" value="adduser">
-</form>
+</div>
+<input type="hidden" name="action" value="adduser">
+<input type="hidden" name="token" value="{{token}}"> \ No newline at end of file
diff --git a/modules-available/adduser/templates/page-edituser.html b/modules-available/adduser/templates/page-edituser.html
new file mode 100644
index 00000000..68376213
--- /dev/null
+++ b/modules-available/adduser/templates/page-edituser.html
@@ -0,0 +1,74 @@
+<input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="position:absolute;top:-2000px" tabindex="-1">
+<input type="password" name="password_fake" id="password_fake" value="" style="position:absolute;top:-2000px" tabindex="-1">
+<h2>{{lang_editUser}}</h2>
+
+<div class="row">
+ <div class="col-md-4"><label for="login">{{lang_login}}</label></div>
+ <div class="col-md-4"><input id="login" type="text" name="login" value="{{login}}" class="form-control event-box"
+ placeholder="{{lang_username}}" autofocus></div>
+</div>
+<div class="row">
+ <div class="col-md-4"></div>
+ <div class="col-md-8">
+ <p>
+ {{lang_changeLoginHint}}
+ </p>
+ </div>
+</div>
+
+<div class="row">
+ <div class="col-md-4"><label for="pass1">{{lang_changePassword}}</label></div>
+ <div class="col-md-4"><input id="pass1" {{password_disabled}} type="password" name="pass1" class="form-control event-box" placeholder="{{lang_password}}">
+ </div>
+ <div class="col-md-4"><input id="pass2" {{password_disabled}} type="password" name="pass2" class="form-control event-box"
+ placeholder="{{lang_confirmation}}"></div>
+</div>
+{{#password_disabled}}
+<div class="row">
+ <div class="col-md-4"></div>
+ <div class="col-md-8">
+ <p>
+ {{lang_changeOwnPasswordHint}}
+ </p>
+ </div>
+</div>
+{{/password_disabled}}
+<br>
+
+<div class="row">
+ <div class="col-md-4"><label for="fullname">{{lang_fullName}}</label></div>
+ <div class="col-md-4"><input id="fullname" type="text" name="fullname" value="{{fullname}}" class="form-control event-box"
+ placeholder="{{lang_fullName}}"></div>
+</div>
+<br>
+
+<div class="row">
+ <div class="col-md-4"><label for="phone">{{lang_phone}}</label></div>
+ <div class="col-md-4"><input id=phone" type="text" name="phone" value="{{phone}}" class="form-control"
+ placeholder="{{lang_phone}}"></div>
+</div>
+<br>
+
+<div class="row">
+ <div class="col-md-4"><label for="email">{{lang_email}}</label></div>
+ <div class="col-md-4"><input id="email" type="text" name="email" value="{{email}}" class="form-control" placeholder="{{lang_email}}">
+ </div>
+</div>
+<br>
+
+<div class="row">
+ <div class="col-md-4"></div>
+ <div class="col-md-8">
+ <button class="btn btn-lg btn-primary btn-block save-btn" type="submit">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ <div id="add-msg" class="text-danger slx-bold"></div>
+ </div>
+</div>
+<input type="hidden" name="action" value="edituser">
+<input type="hidden" name="userid" value="{{userid}}">
+<input type="hidden" name="token" value="{{token}}">
+<script>
+ const SLX_EDITUSER = true;
+</script>
diff --git a/modules-available/adduser/templates/page-userlist.html b/modules-available/adduser/templates/page-userlist.html
new file mode 100644
index 00000000..262553f6
--- /dev/null
+++ b/modules-available/adduser/templates/page-userlist.html
@@ -0,0 +1,87 @@
+<h2>{{lang_userlist}}</h2>
+
+{{{pagenav}}}
+
+<form method="get">
+ <input type="hidden" name="do" value="adduser">
+ <input type="hidden" name="show" value="edituser">
+ <table class="table stupidtable">
+ <thead>
+ <tr>
+ <th data-sort="int" class="slx-smallcol">{{lang_userIdCol}}</th>
+ <th data-sort="string">{{lang_login}}</th>
+ <th data-sort="string">{{lang_name}}</th>
+ <th data-sort="string">{{lang_phone}}</th>
+ <th data-sort="string">{{lang_email}}</th>
+ <th width="1"></th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#list}}
+ <tr>
+ <td class="text-right {{userClass}}">{{userid}}</td>
+ <td id="user-{{userid}}" class="{{userClass}}">{{login}}</td>
+ <td>{{fullname}}</td>
+ <td>{{phone}}</td>
+ <td>{{email}}</td>
+ <td class="text-nowrap">
+ <button class="btn btn-primary btn-xs" {{perms.user.edit.disabled}} type="submit" name="userid" value="{{userid}}">
+ <span class="glyphicon glyphicon-edit"></span>
+ </button>
+ {{^hide_delete}}
+ <button type="button" {{perms.user.remove.disabled}} class="btn btn-danger btn-xs del-user-btn"
+ data-target="#delete-modal" data-toggle="modal" data-user="{{userid}}">
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ {{/hide_delete}}
+ </td>
+ </tr>
+ {{/list}}
+ </tbody>
+ </table>
+ <div class="text-right">
+ <a class="btn btn-success {{perms.user.add.disabled}}" href="?do=adduser&amp;show=adduser">
+ <span class="glyphicon glyphicon-plus"></span>
+ {{lang_addUser}}
+ </a>
+ </div>
+</form>
+<script>
+ document.addEventListener('DOMContentLoaded', function() {
+ $('.del-user-btn').click(function (e) {
+ var uid = $(this).data('user');
+ if (!uid) {
+ alert('ERROR');
+ return false;
+ }
+ $('#delete-userid').val(uid);
+ $('#delete-user-field').text($('#user-' + uid).text());
+ });
+ });
+</script>
+
+<!-- Modals -->
+<div class ="modal fade" id="delete-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <form method="post">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_confirmDelete}}: <span id="delete-user-field"></span></h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_userDeleteConfirm}}</p>
+ </div>
+ <div class="modal-footer">
+ <input type="hidden" name="action" value="deleteuser">
+ <input type="hidden" name="token" value="{{token}}">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" id="delete-userid" name="userid" value="" class="btn btn-danger">
+ <span class="glyphicon glyphicon-trash"></span>
+ {{lang_delete}}
+ </button>
+ </div>
+ </form>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules-available/adduser/templates/user-permissions.html b/modules-available/adduser/templates/user-permissions.html
new file mode 100644
index 00000000..11ebd77a
--- /dev/null
+++ b/modules-available/adduser/templates/user-permissions.html
@@ -0,0 +1,34 @@
+<h3>{{lang_assignRoles}}</h3>
+
+<table class="table table-condensed table-hover">
+ <thead>
+ <tr>
+ <th data-sort="string">{{lang_role}}</th>
+ <th class="text-center slx-smallcol"></th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {{#roles}}
+ <tr>
+ <td class="rolename">{{rolename}}</td>
+ <td class="text-center">
+ <div class="checkbox">
+ <input type="checkbox" name="roles[]" value="{{roleid}}" {{#hasRole}}checked{{/hasRole}}>
+ <label></label>
+ </div>
+ </td>
+ </tr>
+ {{/roles}}
+ </tbody>
+</table>
+
+<div class="row">
+ <div class="col-md-4"></div>
+ <div class="col-md-8">
+ <button class="btn btn-lg btn-primary btn-block save-btn" type="submit">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules-available/backup/config.json b/modules-available/backup/config.json
index 706412d0..110f8b67 100644
--- a/modules-available/backup/config.json
+++ b/modules-available/backup/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.content"
-}
+ "category": "main.content"
+} \ No newline at end of file
diff --git a/modules-available/backup/page.inc.php b/modules-available/backup/page.inc.php
index 949cd7f3..985f39ee 100644
--- a/modules-available/backup/page.inc.php
+++ b/modules-available/backup/page.inc.php
@@ -16,16 +16,19 @@ class Page_Backup extends Page
Util::redirect('?do=Main');
}
$this->action = Request::post('action');
- if ($this->action === 'backup' && User::hasPermission("create")) {
+ if ($this->action === 'backup') {
+ User::assertPermission("create");
$this->backup();
- } elseif ($this->action === 'restore' && User::hasPermission("restore")) {
+ } elseif ($this->action === 'restore') {
+ User::assertPermission("restore");
$this->restore();
}
+ User::assertPermission('*');
}
protected function doRender()
{
- if ($this->action === 'restore' && User::hasPermission("restore")) {
+ if ($this->action === 'restore') { // TODO: We're in post mode, redirect with all the taskids first...
Render::addTemplate('restore', $this->templateData);
} else {
$lastBackup = (int)Property::get(self::LAST_BACKUP_PROP, 0);
@@ -34,9 +37,9 @@ class Page_Backup extends Page
} else {
$lastBackup = date('d.m.Y', $lastBackup);
}
- Render::addTemplate('_page', ['last_backup' => $lastBackup,
- "createAllowed" => User::hasPermission("create"),
- "restoreAllowed" => User::hasPermission("restore")]);
+ $params = ['last_backup' => $lastBackup];
+ Permission::addGlobalTags($params['perms'], NULL, ['create', 'restore']);
+ Render::addTemplate('_page', $params);
}
}
diff --git a/modules-available/backup/permissions/permissions.json b/modules-available/backup/permissions/permissions.json
index feeffe33..1f778ab6 100644
--- a/modules-available/backup/permissions/permissions.json
+++ b/modules-available/backup/permissions/permissions.json
@@ -1,4 +1,8 @@
-[
- "create",
- "restore"
-] \ No newline at end of file
+{
+ "create": {
+ "location-aware": false
+ },
+ "restore": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/backup/style.css b/modules-available/backup/style.css
deleted file mode 100644
index 7b86af56..00000000
--- a/modules-available/backup/style.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.disabledPanel {
- cursor: not-allowed;
-}
-.disabledPanel > .panel-body {
- pointer-events: none;
- opacity: 0.8;
-}
diff --git a/modules-available/backup/templates/_page.html b/modules-available/backup/templates/_page.html
index 41e73091..4c6cade4 100644
--- a/modules-available/backup/templates/_page.html
+++ b/modules-available/backup/templates/_page.html
@@ -3,16 +3,16 @@
<form action="?do=Backup" method="post">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="backup">
- <div class="panel panel-default {{^createAllowed}}disabledPanel{{/createAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">{{lang_backup}}</div>
- <div class="panel-body">
+ <div class="panel-body {{perms.create.disabled}}">
<p>{{lang_backupDescription}}</p>
<p class="text-right">
{{lang_lastBackup}}:
{{^last_backup}}{{lang_unknown}}{{/last_backup}}
{{last_backup}}
</p>
- <button class="btn btn-primary pull-right" type="submit"><span class="glyphicon glyphicon-save"></span> {{lang_download}}</button>
+ <button {{perms.create.disabled}} class="btn btn-primary pull-right" type="submit"><span class="glyphicon glyphicon-save"></span> {{lang_download}}</button>
</div>
</div>
</form>
@@ -20,15 +20,15 @@
<form action="?do=Backup" method="post" enctype="multipart/form-data">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="restore">
- <div class="panel panel-default {{^restoreAllowed}}disabledPanel{{/restoreAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">{{lang_restore}}</div>
- <div class="panel-body">
+ <div class="panel-body {{perms.restore.disabled}}">
<p>{{lang_restoreDescription}}</p>
<div class="input-group upload-ex">
<input type="text" class="form-control" readonly placeholder="{{lang_selectFile}}">
<span class="input-group-btn">
<span class="btn btn-default btn-file">
- {{lang_browseForFile}}&hellip; <input type="file" name="backupfile">
+ {{lang_browseForFile}}&hellip; <input type="file" name="backupfile" {{perms.restore.disabled}}>
</span>
</span>
</div>
@@ -46,7 +46,7 @@
</div>
<p><i>{{lang_dozmodExplanation}}</i></p>
</div>
- <button class="btn btn-primary pull-right" type="submit"><span class="glyphicon glyphicon-open"></span> {{lang_restore}}</button>
+ <button {{perms.restore.disabled}} class="btn btn-primary pull-right" type="submit"><span class="glyphicon glyphicon-open"></span> {{lang_restore}}</button>
</div>
</div>
</form> \ No newline at end of file
diff --git a/modules-available/baseconfig/api.inc.php b/modules-available/baseconfig/api.inc.php
index a4024c5e..bc834930 100644
--- a/modules-available/baseconfig/api.inc.php
+++ b/modules-available/baseconfig/api.inc.php
@@ -16,6 +16,8 @@ class ConfigHolder
private static $context = '';
+ private static $postHooks = [];
+
public static function setContext($name)
{
self::$context = $name;
@@ -54,8 +56,26 @@ class ConfigHolder
return self::$config[$key][0]['value'];
}
+ /**
+ * @param callable $func
+ */
+ public static function addPostHook($func)
+ {
+ self::$postHooks[] = array('context' => self::$context, 'function' => $func);
+ }
+
+ public static function applyPostHooks()
+ {
+ foreach (self::$postHooks as $hook) {
+ self::$context = $hook['context'] . ':post';
+ $hook['function']();
+ }
+ self::$postHooks = [];
+ }
+
public static function getConfig()
{
+ self::applyPostHooks();
$ret = [];
foreach (self::$config as $key => $list) {
if ($list[0]['value'] === false)
@@ -67,6 +87,7 @@ class ConfigHolder
public static function outputConfig()
{
+ self::applyPostHooks();
foreach (self::$config as $key => $list) {
echo '##', $key, "\n";
foreach ($list as $pos => $item) {
@@ -119,7 +140,7 @@ foreach (glob('modules/*/baseconfig/getconfig.inc.php') as $file) {
$mod = Module::get($out[1]);
if ($mod === false)
continue;
- $mod->activate();
+ $mod->activate(1, false);
foreach ($mod->getDependencies() as $dep) {
$depFile = 'modules/' . $dep . '/baseconfig/getconfig.inc.php';
if (file_exists($depFile) && Module::isAvailable($dep)) {
diff --git a/modules-available/baseconfig/config.json b/modules-available/baseconfig/config.json
index e4d906e1..357a117e 100644
--- a/modules-available/baseconfig/config.json
+++ b/modules-available/baseconfig/config.json
@@ -1,4 +1,7 @@
{
"category": "main.settings-client",
- "dependencies" : ["js_selectize", "bootstrap_multiselect"]
-}
+ "dependencies": [
+ "js_selectize",
+ "bootstrap_multiselect"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/de/permissions.json b/modules-available/baseconfig/lang/de/permissions.json
new file mode 100644
index 00000000..a010cebe
--- /dev/null
+++ b/modules-available/baseconfig/lang/de/permissions.json
@@ -0,0 +1,4 @@
+{
+ "edit": "Konfigurationsvariablen bearbeiten",
+ "view": "Konfigurationsvariablen anzeigen"
+} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/en/permissions.json b/modules-available/baseconfig/lang/en/permissions.json
new file mode 100644
index 00000000..9fe69752
--- /dev/null
+++ b/modules-available/baseconfig/lang/en/permissions.json
@@ -0,0 +1,4 @@
+{
+ "edit": "Edit config variables",
+ "view": "Show config variables"
+} \ No newline at end of file
diff --git a/modules-available/baseconfig/page.inc.php b/modules-available/baseconfig/page.inc.php
index 426d3fdd..97fb6072 100644
--- a/modules-available/baseconfig/page.inc.php
+++ b/modules-available/baseconfig/page.inc.php
@@ -13,19 +13,25 @@ class Page_BaseConfig extends Page
protected function doPreprocess()
{
User::load();
+ if (!User::isLoggedIn()) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
// Determine if we're setting global or module specific
$this->getModuleSpecific();
$newValues = Request::post('setting');
if (is_array($newValues)) {
- if (!User::hasPermission('superadmin')) {
- Message::addError('main.no-permission');
- Util::redirect('?do=baseconfig');
+ if ($this->targetModule === 'locations') {
+ User::assertPermission('edit', $this->qry_extra['field_value']);
+ } else {
+ User::assertPermission('edit', 0);
}
// Build variables for specific sub-settings
if ($this->targetModule === false) {
- // We're editing global settings - use the 'enabled' field
+ // We're editing global settings
+ // use the 'enabled' field
$qry_insert = ', enabled';
$qry_values = ', :enabled';
$qry_update = ', enabled = :enabled';
@@ -115,10 +121,6 @@ class Page_BaseConfig extends Page
protected function doRender()
{
- if (!User::hasPermission('superadmin')) {
- Message::addError('main.no-permission');
- Util::redirect('?do=Main');
- }
// Check if valid submodule mode, store name if any
if ($this->targetModule !== false) {
$this->qry_extra['subheading'] = $this->getCurrentModuleName();
@@ -127,6 +129,13 @@ class Page_BaseConfig extends Page
Util::redirect('?do=BaseConfig');
}
}
+ if ($this->targetModule === 'locations') {
+ User::assertPermission('view', $this->qry_extra['field_value']);
+ $editForbidden = !User::hasPermission('edit', $this->qry_extra['field_value']);
+ } else {
+ User::assertPermission('view', 0);
+ $editForbidden = !User::hasPermission('edit', 0);
+ }
// Get stuff that's set in DB already
if ($this->targetModule === false) {
$fields = ', enabled';
@@ -183,15 +192,13 @@ class Page_BaseConfig extends Page
if (!isset($settings[$var['catid']]['settings'][$key]['shadows'])) {
$settings[$var['catid']]['settings'][$key]['shadows'] = isset($var['shadows']) ? $var['shadows'] : null;
}
- //echo "<pre>";
- //var_dump($settings[$var['catid']]['settings'][$key]);
- //echo "</pre>";
$settings[$var['catid']]['settings'][$key] += array(
'item' => $this->makeInput(
$var['validator'],
$key,
$settings[$var['catid']]['settings'][$key]['displayvalue'],
- $settings[$var['catid']]['settings'][$key]['shadows']
+ $settings[$var['catid']]['settings'][$key]['shadows'],
+ $editForbidden
),
'description' => Util::markup(Dictionary::translateFileModule($var['module'], 'config-variables', $key)),
'setting' => $key,
@@ -218,6 +225,7 @@ class Page_BaseConfig extends Page
'override' => $this->targetModule !== false,
'categories' => array_values($settings),
'target_module' => $this->targetModule,
+ 'edit_disabled' => $editForbidden ? 'disabled' : '',
) + $this->qry_extra);
Module::isAvailable('bootstrap_switch');
}
@@ -296,13 +304,16 @@ class Page_BaseConfig extends Page
* @param string $validator
* @return boolean
*/
- private function makeInput($validator, $setting, $current, $shadows)
+ private function makeInput($validator, $setting, $current, $shadows, $disabled)
{
/* for the html snippet we need: */
$args = array('class' => 'form-control', 'name' => "setting[$setting]", 'id' => $setting);
if (!empty($shadows)) {
$args['data-shadows'] = json_encode($shadows);
}
+ if ($disabled) {
+ $args['disabled'] = true;
+ }
$inner = "";
/* -- */
@@ -360,10 +371,13 @@ class Page_BaseConfig extends Page
$output = "<$tag ";
foreach ($args as $key => $val) {
+ if ($val === true) {
+ $output .= $key . ' ';
+ }
$output .= "$key=\"" . htmlspecialchars($val) . '" ';
}
if (empty($inner)) {
- $output .= '/>';
+ $output .= '>';
} else {
$output .= '>' . $inner . "</$tag>";
}
diff --git a/modules-available/baseconfig/permissions/permissions.json b/modules-available/baseconfig/permissions/permissions.json
new file mode 100644
index 00000000..9edefdfb
--- /dev/null
+++ b/modules-available/baseconfig/permissions/permissions.json
@@ -0,0 +1,8 @@
+{
+ "view": {
+ "location-aware": true
+ },
+ "edit": {
+ "location-aware": true
+ }
+} \ No newline at end of file
diff --git a/modules-available/baseconfig/templates/_page.html b/modules-available/baseconfig/templates/_page.html
index 89caf9f2..110ee5ec 100644
--- a/modules-available/baseconfig/templates/_page.html
+++ b/modules-available/baseconfig/templates/_page.html
@@ -29,7 +29,7 @@
{{#defaultvalue}}{{lang_defaultValue}}:{{/defaultvalue}}
{{defaultvalue}}
</div>
- <input class="bs-switch" name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}}>
+ <input class="bs-switch" name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}} {{edit_disabled}}>
<label for="CB_{{setting}}">
{{#override}}{{lang_enableOverride}}{{/override}}
{{^override}}{{lang_settingActive}}{{/override}}
@@ -73,7 +73,7 @@
{{#override}}
<a class="btn btn-default" href="api.php?do=baseconfig&amp;user={{userid}}&amp;module={{target_module}}&amp;value={{field_value}}&amp;force=1">Download</a>
{{/override}}
- <button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button class="btn btn-primary" type="submit" {{edit_disabled}}><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
<br/>
@@ -86,6 +86,8 @@ function updateShadows(e) {
if (!rules) return;
var currentValue = $(e).val();
for (var triggerVal in rules) {
+ if (!rules.hasOwnProperty(triggerVal))
+ continue;
var targets = rules[triggerVal];
for (var i = 0; i < targets.length; ++i) {
var target = targets[i];
@@ -95,11 +97,11 @@ function updateShadows(e) {
if (currentValue === triggerVal) {
inp.prop('disabled', true);
if (selitem) selitem.disable();
- $('#' + target + '.multilist').multiselect('disable');
+ inp.filter('.multiselect').multiselect('disable');
} else {
inp.prop('disabled', false);
if (selitem) selitem.enable();
- $('#' + target + '.multilist').multiselect('enable');
+ inp.filter('.multiselect').multiselect('enable');
}
}
}
@@ -125,6 +127,7 @@ document.addEventListener("DOMContentLoaded", function () {
buttonWidth: '100%',
buttonClass: 'form-control'
});
+ $('select.multiselect').filter(':disabled').multiselect('disable');
/* data-shadowing bindings */
var $allShadowingFields = $('[data-shadows]');
diff --git a/modules-available/baseconfig_bwidm/config.json b/modules-available/baseconfig_bwidm/config.json
index af67a188..7e6cf06a 100644
--- a/modules-available/baseconfig_bwidm/config.json
+++ b/modules-available/baseconfig_bwidm/config.json
@@ -1,3 +1,5 @@
{
- "dependencies": ["baseconfig"]
-}
+ "dependencies": [
+ "baseconfig"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_bwidm/hooks/translation.inc.php b/modules-available/baseconfig_bwidm/hooks/translation.inc.php
index 5ccafbc4..a53500fc 100644
--- a/modules-available/baseconfig_bwidm/hooks/translation.inc.php
+++ b/modules-available/baseconfig_bwidm/hooks/translation.inc.php
@@ -20,7 +20,7 @@ $HANDLER['subsections'] = array(
* @return array
*/
$HANDLER['grep_config-variable-categories'] = function($module) {
- if (!$module->activate())
+ if (!$module->activate(1, false))
return array();
$want = BaseConfigUtil::getCategories($module);
foreach ($want as &$entry) {
@@ -35,7 +35,7 @@ $HANDLER['grep_config-variable-categories'] = function($module) {
* @return array
*/
$HANDLER['grep_config-variables'] = function($module) {
- if (!$module->activate())
+ if (!$module->activate(1, false))
return array();
$want = BaseConfigUtil::getVariables($module);
foreach ($want as &$entry) {
diff --git a/modules-available/baseconfig_bwlp/baseconfig/settings.json b/modules-available/baseconfig_bwlp/baseconfig/settings.json
index 0d4db4d4..6aab113e 100644
--- a/modules-available/baseconfig_bwlp/baseconfig/settings.json
+++ b/modules-available/baseconfig_bwlp/baseconfig/settings.json
@@ -121,6 +121,18 @@
"permissions": "2",
"validator": "regex:\/^\\d*$\/"
},
+ "SLX_SCREEN_SAVER_TIMEOUT": {
+ "catid": "power",
+ "defaultvalue": "540",
+ "permissions": "2",
+ "validator": "regex:\/^\\d*$\/"
+ },
+ "SLX_SCREEN_SAVER_GRACE_TIMEOUT": {
+ "catid": "power",
+ "defaultvalue": "15",
+ "permissions": "2",
+ "validator": "regex:\/^\\d*$\/"
+ },
"SLX_SCREEN_STANDBY_TIMEOUT": {
"catid": "power",
"defaultvalue": "600",
@@ -186,6 +198,12 @@
]
}
},
+ "SLX_PREFERRED_SOUND_OUTPUT": {
+ "catid": "sysconfig",
+ "defaultvalue": "SOUNDCARD",
+ "permissions": "2",
+ "validator": "list:HDMI|SOUNDCARD"
+ },
"SLX_PVS_DEFAULT": {
"catid": "vmchooser",
"defaultvalue": "OFF",
diff --git a/modules-available/baseconfig_bwlp/config.json b/modules-available/baseconfig_bwlp/config.json
index af67a188..7e6cf06a 100644
--- a/modules-available/baseconfig_bwlp/config.json
+++ b/modules-available/baseconfig_bwlp/config.json
@@ -1,3 +1,5 @@
{
- "dependencies": ["baseconfig"]
-}
+ "dependencies": [
+ "baseconfig"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_bwlp/hooks/translation.inc.php b/modules-available/baseconfig_bwlp/hooks/translation.inc.php
index 5ccafbc4..a53500fc 100644
--- a/modules-available/baseconfig_bwlp/hooks/translation.inc.php
+++ b/modules-available/baseconfig_bwlp/hooks/translation.inc.php
@@ -20,7 +20,7 @@ $HANDLER['subsections'] = array(
* @return array
*/
$HANDLER['grep_config-variable-categories'] = function($module) {
- if (!$module->activate())
+ if (!$module->activate(1, false))
return array();
$want = BaseConfigUtil::getCategories($module);
foreach ($want as &$entry) {
@@ -35,7 +35,7 @@ $HANDLER['grep_config-variable-categories'] = function($module) {
* @return array
*/
$HANDLER['grep_config-variables'] = function($module) {
- if (!$module->activate())
+ if (!$module->activate(1, false))
return array();
$want = BaseConfigUtil::getVariables($module);
foreach ($want as &$entry) {
diff --git a/modules-available/baseconfig_bwlp/lang/de/config-variables.json b/modules-available/baseconfig_bwlp/lang/de/config-variables.json
index ad2abc8d..78481da9 100644
--- a/modules-available/baseconfig_bwlp/lang/de/config-variables.json
+++ b/modules-available/baseconfig_bwlp/lang/de/config-variables.json
@@ -4,13 +4,14 @@
"SLX_AUTOSTART_UUID": "ID einer Veranstaltung die automatisch gestartet werden soll. Die Veranstaltungs-ID finden Sie im Detailfenster innerhalb der bwLehrpool-Suite.\r\n\r\n*Hinweis: Diese Option ist eine tempor\u00e4re \u00dcbergangsl\u00f6sung. In sp\u00e4teren Versionen wird die Funktionalit\u00e4t einfacher erreichbar sein.*",
"SLX_BIOS_CLOCK": "Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des \/MiniLinux\/ gesetzt werden soll.\r\n*off* = Die interne Uhr des Rechners wird nicht ver\u00e4ndert.\r\n*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.\r\n*utc* = Die interne Uhr wird auf die \/Koordinierte Weltzeit\/ gesetzt. Dies ist die g\u00e4ngige Einstellung in einem reinen Linux-Umfeld.",
"SLX_BRIDGE_OTHER_NICS": "Sofern ein Client mehrere Netzwerkkarten besitzt, k\u00f6nnen Sie mittels dieser Option alle weiteren gefundenen Karten in die VM durchreichen.",
- "SLX_DEMO_PASS": "Passwort f\u00fcr den eingebauten *demo*-Account. Leer lassen, um das Einloggen zu verbieten.\r\nDas Passwort wird wie das root-Passwort nur gehasht an den Client \u00fcbertragen.",
+ "SLX_DEMO_PASS": "Passwort f\u00fcr den eingebauten *demo*-Account. Leer lassen, um das Einloggen zu verbieten.\r\n\/Hinweis\/: Das Passwort wird im Klartext in der lokalen Datenbank hinterlegt, jedoch immer gehasht an die Clients \u00fcbermittelt (SHA-512 mit Salt). Wenn Sie das Passwort auch im Satelliten nicht im Klartext speichern wollen, k\u00f6nnen Sie hier auch ein vorgehashtes Passwort eintragen (im *$6$....*-Format).",
"SLX_JUMBO_FRAMES": "Setzt die MTU auf den Clients auf 9000, statt wie \u00fcblich 1500. Da dies mit alten\/schlechten Routern oder Switches zu Problemen f\u00fchren k\u00f6nnte, ist diese Option standardm\u00e4\u00dfig deaktiviert.",
"SLX_LOGOUT_TIMEOUT": "Zeit in Sekunden, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.Feld leer lassen, um die Funktion zu deaktivieren.",
"SLX_NET_DOMAIN": "DNS-Dom\u00e4ne, in die sich die Clients eingliedern, sofern der DHCP Server keine solche vorgibt.",
"SLX_NET_SEARCH": "Per Leerzeichen getrennte Liste von Suchdom\u00e4nen, die der Client verwenden soll, sofern der DHCP-Server keine Vorgabe macht.",
"SLX_NTP_SERVER": "Adresse des NTP-Zeitservers. Es k\u00f6nnen mehrere Server mit Leerzeichen getrennt angegeben werden.Die Server werden der Reihe nach angefragt, bis ein antwortender Server gefunden wird.",
"SLX_PASSTHROUGH_USB_ID": "Geben Sie hier eindeutige IDs von USB-Ger\u00e4ten an, die direkt in die VMs weitergereicht werden sollen. Das erwartete Format ist *vendorID:productID* , als jeweils vierstellige Hexadezimalzahlen, beispielsweise *1234:abcd* .\r\nMehrere IDs k\u00f6nnen als leerzeichengetrennte Liste angegeben werden.",
+ "SLX_PREFERRED_SOUND_OUTPUT": "Bevorzugte Ausgabemethode f\u00fcr Sound. Standardm\u00e4\u00dfig werden dedizierte Soundkarten bevorzugt, da die Ausgabe \u00fcber HDMI mitunter Probleme bereiten kann, besonders wenn im Betrieb Bildschirme an- oder abgesteckt werden.",
"SLX_PRINT_USER_PREFIX": "Pr\u00e4fix, was im Authentifizierungsdialog der PrinterGUI dem Benutzernamen vorangestellt wird.\r\nWenn das Drucksystem auf einem AD-Server l\u00e4uft und der Dom\u00e4nenname vorangestellt werden muss, tragen Sie hier *domain\\* ein. Achten Sie auf die Angabe des Backslashes, er wird nicht automatisch angeh\u00e4ngt. Falls das Drucksystem mit dem reinen Benutzernamen zurecht kommt, k\u00f6nnen Sie das Feld leer lassen.",
"SLX_PROXY_BLACKLIST": "Adressen bzw. Adressbereiche, f\u00fcr die der Proxyserver nicht verwendet werden soll (z.B. der Adressbereich der Einrichtung). G\u00fcltige Angaben sind einzelne IP-Adressen, sowie IP-Bereiche in CIDR-Notation (z.B. 1.2.0.0\/16). Mehrere Angaben k\u00f6nnen durch Leerzeichen getrennt werden.",
"SLX_PROXY_IP": "Die Adresse des zu verwendenden Proxy Servers.",
@@ -21,6 +22,8 @@
"SLX_REBOOT_SCHEDULE": "Feste Uhrzeit, zu der sich die Rechner neustarten, auch wenn noch ein Benutzer aktiv ist.\r\nMehrere Zeitpunkte k\u00f6nnen durch Leerzeichen getrennt angegeben werden.",
"SLX_REMOTE_LOG_SESSIONS": "Legt fest, ob Logins und Logouts der Benutzer an den Satelliten gemeldet werden sollen.\r\n*yes* = Mit Benutzerkennung loggen\r\n*anonymous* = Anonym loggen\r\n*no* = Nicht loggen",
"SLX_ROOT_PASS": "Das root-Passwort des Grundsystems. Wird nur f\u00fcr Diagnosezwecke am Client ben\u00f6tigt.\r\nFeld leer lassen, um root-Logins zu verbieten.\r\n\/Hinweis\/: Das Passwort wird im Klartext in der lokalen Datenbank hinterlegt, jedoch immer gehasht an die Clients \u00fcbermittelt (SHA-512 mit Salt). Wenn Sie das Passwort auch im Satelliten nicht im Klartext speichern wollen, k\u00f6nnen Sie hier auch ein vorgehashtes Passwort eintragen (im *$6$....*-Format).",
+ "SLX_SCREEN_SAVER_GRACE_TIMEOUT": "Wenn sich der Bildschirmschoner nach dem konfigurierten Timeout automatisch aktiviert, kann er f\u00fcr die hier angegebene Zeit (in Sekunden) durch Tastendruck oder Mausbewegen wieder deaktiviert werden, ohne dass das Benutzerkennwort angefordert wird.",
+ "SLX_SCREEN_SAVER_TIMEOUT": "Zeit in Sekunden, nach der sich bei Nutzerinaktivit\u00e4t der Bildschirmschoner aktiviert. Der Bildschirmschoner sperrt zugleich die Sitzung und fordert zum Entsperren das Nutzerkennwort an.",
"SLX_SCREEN_STANDBY_TIMEOUT": "Zeit in Sekunden, nach der der Bildschirm bei Inaktivit\u00e4t des Rechners in den Standby-Modus versetzt wird.",
"SLX_SHUTDOWN_SCHEDULE": "Feste Uhrzeit, zu der sich die Rechner ausschalten, auch wenn noch ein Benutzer aktiv ist.\r\nMehrere Zeitpunkte k\u00f6nnen durch Leerzeichen getrennt angegeben werden.",
"SLX_SHUTDOWN_TIMEOUT": "Zeit in Sekunden, nach der ein Rechner abgeschaltet wird, sofern kein Benutzer angemeldet ist.\r\nFeld leer lassen, um die Funktion zu deaktivieren.",
diff --git a/modules-available/baseconfig_bwlp/lang/en/config-variables.json b/modules-available/baseconfig_bwlp/lang/en/config-variables.json
index c56f171d..9fd65053 100644
--- a/modules-available/baseconfig_bwlp/lang/en/config-variables.json
+++ b/modules-available/baseconfig_bwlp/lang/en/config-variables.json
@@ -4,13 +4,14 @@
"SLX_AUTOSTART_UUID": "ID of a lecture which is automatically started. The lecture-ID is found in the detail window of a lecture in the bwLehrpool-Suite. \r\n\r\n*This solution is only temporary. In later versions this feature will probably be moved to another section*",
"SLX_BIOS_CLOCK": "Specifies whether and how the internal clock of the computer should be set in relation to the system time of the \/MiniLinux\/.\r\n*off* = The internal clock of the computer is not changed.\r\n*local* = The internal clock is set to local time. Preferably if, for example, there is still a native Windows installation available on the PC.\r\n*utc* = The internal clock is set to the \/Coordinated Universal Time\/. This is the most common setup in a pure Linux environment.",
"SLX_BRIDGE_OTHER_NICS": "If enabled, additional network cards installed in the Client will be bridged to the VM. ",
- "SLX_DEMO_PASS": "Password for the *demo* account. Leave empty to disallow logging in as the demo user.\r\nLike the root password, the demo user's password will be sent to the client in its hashed form.",
+ "SLX_DEMO_PASS": "Password for the *demo* account. Leave empty to disallow logging in as the demo user.\r\n\/Hint\/: The password SHA-512-with-salt hashed before it's being sent to the client. It's only stored in clear text on the Satellite Server. If you want to have it hashed on the server too, you can supply a pre-hashed password in \/$6$...$...\/-format.",
"SLX_JUMBO_FRAMES": "Increases the MTU on the clients from 1500 to 9000. As this can lead to issues with old\/bad routers and switches, this option is disabled by default.",
"SLX_LOGOUT_TIMEOUT": "Time in seconds, in which a user session may remain without action before it is terminated.Leave field blank to disable the function.",
"SLX_NET_DOMAIN": "DNS domain in which the client integrate, provided the DHCP server does not specifies such.",
"SLX_NET_SEARCH": "Space separated list of DNS search domains to use in case the DHCP server doesn't supply any.",
"SLX_NTP_SERVER": "Address of the NTP time server. Multiple servers can be specified separated by spaces.The servers are queried in sequence until a responding server is found.",
"SLX_PASSTHROUGH_USB_ID": "Specify IDs of USB devices that should be passed through to the VM directly.\r\nThe expected format is *vendorID:productID* , where each ID is a 4-digit hexadecimal number, e.g. *1234:abcd* \r\nMultiple IDs can be given as a space-separated list.",
+ "SLX_PREFERRED_SOUND_OUTPUT": "Preferred sound output method.\r\nDefaults to dedicated sound card, since using HDMI can be unreliable, especially if screens get (un)plugged while the (virtual) machine is running.",
"SLX_PRINT_USER_PREFIX": "Prefix to add to the user name in the authentication dialog of PrinterGUI.\r\nIf your print server belongs to a Windows domain and requires the domain name prefixed, set this field to *domainname\\*. Note the trailing backslash, it will not be inserted automatically. If your print server just wants the plain user name, this field should be left blank.",
"SLX_PROXY_BLACKLIST": "Address or addresses ranges in which the proxy server is not used (for example the address range of the device). Valid entries are individual IP addresses and IP ranges in CIDR notation (for example 1.2.0.0\/16). Multiple selections can be separated by spaces.",
"SLX_PROXY_IP": "The address to use for the proxy server.",
@@ -20,7 +21,9 @@
"SLX_PVS_DEFAULT": "Set whether the \"Join PVS\" checkbox in vmChooser is checked by default.",
"SLX_REBOOT_SCHEDULE": "Fixed time to reboot the computer, even if there is a user active.\r\nSeveral times can be specified, separated by spaces.",
"SLX_REMOTE_LOG_SESSIONS": "Determines whether logins and logouts of the users should be reported to the satellite.\r\n*yes* = log with user ID\r\n*anonymous* = anonymous logging\r\n*no* = no logging",
- "SLX_ROOT_PASS": "The root password of the client system. Only required for diagnostic purposes on the client.Leave field blank to disallow root logins.\r\n\/Hint\/: The password SHA-512-with-salt hashed before it's being sent to the client. It's only stored in clear text on the Satellite Server. If you want to have it hashed on the server too, you can supply a pre-hashed passoword in \/$6$...$...\/-format.",
+ "SLX_ROOT_PASS": "The root password of the client system. Only required for diagnostic purposes on the client.Leave field blank to disallow root logins.\r\n\/Hint\/: The password SHA-512-with-salt hashed before it's being sent to the client. It's only stored in clear text on the Satellite Server. If you want to have it hashed on the server too, you can supply a pre-hashed password in \/$6$...$...\/-format.",
+ "SLX_SCREEN_SAVER_GRACE_TIMEOUT": "If the screen saver activates after the configured timeout, the user can disable it again by just moving the mouse or pressing a key, without entering their password again. This is called the screen saver grace period, which is configurable in seconds.",
+ "SLX_SCREEN_SAVER_TIMEOUT": "Timeout for screen saver activation. If the user is idle for this long (in seconds), the screen saver will activate and lock the screen, so the user password is required to unlock the screen again.",
"SLX_SCREEN_STANDBY_TIMEOUT": "Time in seconds after which the screen will enter power saving mode, if the client is not in use.",
"SLX_SHUTDOWN_SCHEDULE": "Fixed time to turn off the computer, even if there is a user active.\r\nSeveral times can be specified, separated by spaces.",
"SLX_SHUTDOWN_TIMEOUT": "Time in seconds after which a computer is switched off, if no user is logged on.\r\nLeave blank to disable the function.",
diff --git a/modules-available/baseconfig_partitions_cdn/config.json b/modules-available/baseconfig_partitions_cdn/config.json
index a355eef3..fd4c6f4b 100644
--- a/modules-available/baseconfig_partitions_cdn/config.json
+++ b/modules-available/baseconfig_partitions_cdn/config.json
@@ -1,4 +1,6 @@
{
- "category": "main.settings-client",
- "dependencies": [ "baseconfig" ]
-}
+ "category": "main.settings-client",
+ "dependencies": [
+ "baseconfig"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/lang/de/permissions.json b/modules-available/baseconfig_partitions_cdn/lang/de/permissions.json
new file mode 100644
index 00000000..d5805e3d
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/lang/de/permissions.json
@@ -0,0 +1,7 @@
+{
+ "show": "Zeige Partitionen. Wird nicht benötigt, wenn Nutzer eine der anderen Rechte hat.",
+ "partitions.add": "Füge eine neue Partition hinzu.",
+ "partitions.delete": "Lösche eine Partition.",
+ "partitions.edit": "Speichere Änderungen an Partitionen.",
+ "partitions.reset": "Setze Partitionen auf Standardwerte zurück."
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/lang/en/permissions.json b/modules-available/baseconfig_partitions_cdn/lang/en/permissions.json
new file mode 100644
index 00000000..f751a839
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/lang/en/permissions.json
@@ -0,0 +1,7 @@
+{
+ "show": "Show Partitions. Not needed if User has any of the other permissions.",
+ "partitions.add": "Add a new partition.",
+ "partitions.delete": "Delete a partition.",
+ "partitions.edit": "Save changes of partitions.",
+ "partitions.reset": "Reset partitions to default."
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json b/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json
index 04ce6c80..472e5870 100644
--- a/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json
+++ b/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json
@@ -1,9 +1,9 @@
{
"lang_areYouSureNoUndo": "Are you sure? This cannot be undone!",
- "lang_confirm": "Would you like to save the settings on [ \/srv\/openslx\/www\/boot\/config ] ?",
+ "lang_confirm": "Would you like to save the settings on \/srv\/openslx\/www\/boot\/config?",
"lang_create": "Create",
"lang_discardChanges": "Discard Changes",
- "lang_explanationText": "Here you can configure what kind of partitions will be created on the client computers, and where they will be mounted",
+ "lang_explanationText": "Here you can configure what kind of partitions will be created on the client computers, and where they will be mounted.",
"lang_helpId": "Partition Id",
"lang_helpMountPoint": "Must be a directory: \/example\/directory\/",
"lang_helpOptions": "Currently, only option 'bootable' is available",
diff --git a/modules-available/baseconfig_partitions_cdn/page.inc.php b/modules-available/baseconfig_partitions_cdn/page.inc.php
index a1d1445f..b61ea448 100644
--- a/modules-available/baseconfig_partitions_cdn/page.inc.php
+++ b/modules-available/baseconfig_partitions_cdn/page.inc.php
@@ -10,23 +10,39 @@ class Page_BaseConfig_Partitions_CDN extends Page
$action = Request::post('action');
if($action == 'new_partition') {
- $this->addPartition();
+ if (User::hasPermission("partitions.add")) {
+ $this->addPartition();
+ }
}
if($action == 'reset') {
- $this->resetConfig();
+ if (User::hasPermission("partitions.reset")) {
+ $this->resetConfig();
+ }
}
$deletePartition = Request::get('deletePartition');
if($deletePartition !== false) { // TODO: CSRF: Actions that change/update/delete anything should be POST
- $this->deletePartition($deletePartition);
+ if (User::hasPermission("partitions.delete")) {
+ $this->deletePartition($deletePartition);
+ }
}
- $this->updatePartitions();
+ if(User::hasPermission("partitions.edit")) {
+ $this->updatePartitions();
+ }
}
protected function doRender()
{
- if (!User::hasPermission('baseconfig_local')) {
+ if (!User::isLoggedIn()) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
+
+ $hasAnyRight = User::hasPermission("partitions.add") || User::hasPermission("partitions.delete")
+ || User::hasPermission("partitions.edit") || User::hasPermission("partitions.reset");
+
+ if (!(User::hasPermission("show") || $hasAnyRight)) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
@@ -48,7 +64,11 @@ class Page_BaseConfig_Partitions_CDN extends Page
Render::addTemplate('_page', array(
'partitions' => $partitions,
- 'user' => User::getId()
+ 'user' => User::getId(),
+ 'allowedToAdd' => User::hasPermission("partitions.add"),
+ 'allowedToDelete' => User::hasPermission("partitions.delete"),
+ 'allowedToEdit' => User::hasPermission("partitions.edit"),
+ 'allowedToReset' => User::hasPermission("partitions.reset")
));
}
@@ -92,9 +112,9 @@ class Page_BaseConfig_Partitions_CDN extends Page
private function updatePartitions(){
$partitions = array();
foreach($_POST as $key => $value){
- if(substr($key,0,9) == 'partition'){
- $id = substr($key,10,1);
- $type = substr($key,12);
+
+ if (substr($key, 0, 9) == 'partition') {
+ list($key, $id, $type) = explode("-", $key);
$partitions[$id][$type] = $value;
}
}
@@ -111,6 +131,8 @@ class Page_BaseConfig_Partitions_CDN extends Page
Database::exec('UPDATE setting_partition SET partition_id=:partition_id, size=:size, mount_point=:mount_point,
options=:options WHERE id=:id AND user=:user;', $data);
}
+
+
if (!empty($partitions)) {
Message::addSuccess('partitions-updated');
Util::redirect('?do=BaseConfig_Partitions_CDN');
@@ -129,5 +151,6 @@ class Page_BaseConfig_Partitions_CDN extends Page
Database::exec ( "INSERT INTO setting_partition SET partition_id = '40', size = '20G', mount_point = '/cache/export/dnbd3', user = :user", $data );
Database::exec ( "INSERT INTO setting_partition SET partition_id = '41', size = '5G', mount_point = '/home', user = :user", $data );
Database::exec ( "INSERT INTO setting_partition SET partition_id = '82', size = '1G', user = :user", $data );
+ Util::redirect('?do=BaseConfig_Partitions_CDN');
}
} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/permissions/permissions.json b/modules-available/baseconfig_partitions_cdn/permissions/permissions.json
new file mode 100644
index 00000000..3acd5230
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/permissions/permissions.json
@@ -0,0 +1,17 @@
+{
+ "partitions.add": {
+ "location-aware": false
+ },
+ "partitions.delete": {
+ "location-aware": false
+ },
+ "partitions.edit": {
+ "location-aware": false
+ },
+ "partitions.reset": {
+ "location-aware": false
+ },
+ "show": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/style.css b/modules-available/baseconfig_partitions_cdn/style.css
new file mode 100644
index 00000000..d55e5e5b
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/style.css
@@ -0,0 +1,4 @@
+.missingInput {
+ border-color: rgba(255, 0, 0, 0.8);
+ box-shadow: 0 1px 1px rgba(255, 0, 0, 0.075) inset, 0 0 8px rgba(255, 0, 0, 0.6);
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/templates/_page.html b/modules-available/baseconfig_partitions_cdn/templates/_page.html
index 71cbb7db..2cb3f2a6 100644
--- a/modules-available/baseconfig_partitions_cdn/templates/_page.html
+++ b/modules-available/baseconfig_partitions_cdn/templates/_page.html
@@ -21,7 +21,7 @@
<input name='partition-{{id}}-options' type='text' class='form-control' size='30' value='{{options}}' placeholder='{{lang_partitionOptions}}'/>
</div>
<div class='col-sm-1 col-md-2'>
- <a class='btn btn-danger' href='?do=BaseConfig_Partitions_CDN&amp;deletePartition={{id}}&amp;token={{token}}'>
+ <a class='btn btn-danger btn-sm {{allowedToDelete}}disabled{{allowedToDelete}}' href='?do=BaseConfig_Partitions_CDN&amp;deletePartition={{id}}&amp;token={{token}}'>
<span class='glyphicon glyphicon-trash'></span>
</a>
</div>
@@ -30,16 +30,16 @@
{{/partitions}}
<div class='list-group-item clearfix'>
<div class="pull-right">
- <a class='btn btn-success ' data-toggle='modal' data-target='#add-partition'>
+ <button {{^allowedToAdd}}disabled{{/allowedToAdd}} type="button" class='btn btn-success' data-toggle='modal' data-target='#add-partition'>
<span class='glyphicon glyphicon-plus'></span> {{lang_newPartition}}
- </a>
+ </button>
</div>
</div>
</div>
<div class="pull-right">
- <a class="btn btn-default" data-toggle="modal" data-target="#downloadModal"><span class="glyphicon glyphicon-download-alt"></span> Download</a>
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#downloadModal"><span class="glyphicon glyphicon-download-alt"></span> Download</button>
<button class="btn btn-warning" type="reset"><span class="glyphicon glyphicon-refresh"></span> {{lang_discardChanges}}</button>
- <button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button {{^allowedToEdit}}disabled{{/allowedToEdit}} class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
<div class ="modal fade" id="downloadModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
@@ -49,8 +49,10 @@
{{lang_confirm}}
</div>
<div class="modal-footer">
- <button type="button" onclick="saveConfig(false)" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="button" onclick="saveConfig(true)" class="btn btn-sm btn-danger" name="download"> Download</button>
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="button" onclick="saveConfig()" class="btn btn-primary" name="download">
+ <span class="glyphicon glyphicon-download-alt"></span> Download
+ </button>
</div>
</div>
</div>
@@ -60,7 +62,7 @@
<form method="post" action="?do=BaseConfig_Partitions_CDN">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="reset">
- <button class="btn btn-danger" type="button" data-toggle="modal" data-target="#resetDefaultModal">{{lang_resetDefault}}</button>
+ <button {{^allowedToReset}}disabled{{/allowedToReset}} class="btn btn-danger" type="button" data-toggle="modal" data-target="#resetDefaultModal">{{lang_resetDefault}}</button>
<div class ="modal fade" id="resetDefaultModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" style="width: 400px" role="document">
@@ -70,7 +72,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="submit" class="btn btn-sm btn-danger" name="resetDefault"> {{lang_resetDefault}}</button>
+ <button type="submit" class="btn btn-danger" name="resetDefault"> {{lang_resetDefault}}</button>
</div>
</div>
</div>
@@ -78,7 +80,7 @@
</form>
<!-- Create Partition Window -->
-<form action="?do=BaseConfig_Partitions_CDN" method="post">
+<form id="createPartitionForm" action="?do=BaseConfig_Partitions_CDN" method="post">
<div class="modal fade" id="add-partition" tabindex="-1" role="dialog">
<div class="modal-dialog">
@@ -89,12 +91,12 @@
<div class="modal-body">
<div class="input-group">
- <span class="input-group-addon" style="min-width:140px;">{{lang_partitionId}}</span>
+ <span class="input-group-addon" style="min-width:140px;">{{lang_partitionId}} *</span>
<input name="new-partition-id" class="form-control" type="text">
</div>
<p class="help-block">{{lang_helpId}}</p>
<div class="input-group">
- <span class="input-group-addon" style="min-width:140px;">{{lang_partitionSize}}</span>
+ <span class="input-group-addon" style="min-width:140px;">{{lang_partitionSize}} *</span>
<input name="new-partition-size" class="form-control" type="text">
</div>
<p class="help-block">{{lang_helpSize}}</p>
@@ -111,8 +113,10 @@
</div>
<div class="modal-footer">
- <a class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</a>
- <input type="submit" class="btn btn-primary" value="{{lang_create}}">
+ <button class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-success">
+ <span class='glyphicon glyphicon-plus'></span> {{lang_create}}
+ </button>
</div>
</div>
</div>
@@ -120,12 +124,28 @@
<input type="hidden" name="action" value="new_partition">
<input type="hidden" name="token" value="{{token}}">
</form>
+
<script type="text/javascript">
- function saveConfig(download){
- if(download)
- window.location = 'api.php?do=baseconfig&user={{user}}&save=true';
- else
- window.location = 'api.php?do=baseconfig&user={{user}}';
- }
+ document.addEventListener("DOMContentLoaded", function () {
+ $("#createPartitionForm").submit(function () {
+ var input1 = $("input[name=new-partition-id]");
+ var input2 = $("input[name=new-partition-size]");
+ var id = $.trim(input1.val());
+ var size = $.trim(input2.val());
+ if (!id) {
+ input1.addClass("missingInput");
+ }
+ if (!size) {
+ input2.addClass("missingInput");
+ }
+ if (!id || !size) {
+ return false;
+ }
+ });
+ });
+
+ function saveConfig(){
+ window.location = 'api.php?do=baseconfig&user={{user}}&save=true';
+ }
</script> \ No newline at end of file
diff --git a/modules-available/bootstrap_datepicker/config.json b/modules-available/bootstrap_datepicker/config.json
index 5a0c7960..69bb0aa9 100644
--- a/modules-available/bootstrap_datepicker/config.json
+++ b/modules-available/bootstrap_datepicker/config.json
@@ -1,9 +1,10 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/bootstrap_dialog/config.json b/modules-available/bootstrap_dialog/config.json
index 5a0c7960..69bb0aa9 100644
--- a/modules-available/bootstrap_dialog/config.json
+++ b/modules-available/bootstrap_dialog/config.json
@@ -1,9 +1,10 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/bootstrap_multiselect/config.json b/modules-available/bootstrap_multiselect/config.json
index 5a0c7960..69bb0aa9 100644
--- a/modules-available/bootstrap_multiselect/config.json
+++ b/modules-available/bootstrap_multiselect/config.json
@@ -1,9 +1,10 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/bootstrap_switch/config.json b/modules-available/bootstrap_switch/config.json
index de4d37b4..3cf0d162 100644
--- a/modules-available/bootstrap_switch/config.json
+++ b/modules-available/bootstrap_switch/config.json
@@ -1,8 +1,9 @@
{
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
} \ No newline at end of file
diff --git a/modules-available/bootstrap_timepicker/config.json b/modules-available/bootstrap_timepicker/config.json
index 5a0c7960..69bb0aa9 100644
--- a/modules-available/bootstrap_timepicker/config.json
+++ b/modules-available/bootstrap_timepicker/config.json
@@ -1,9 +1,10 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/citymanagement/config.json b/modules-available/citymanagement/config.json
index e87cbf7d..b356dfc6 100644
--- a/modules-available/citymanagement/config.json
+++ b/modules-available/citymanagement/config.json
@@ -1,4 +1,4 @@
{
- "category":"citymanagement.cities",
- "permission":"0"
-}
+ "category": "citymanagement.cities",
+ "permission": "0"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/config.json b/modules-available/dnbd3/config.json
index f84a4170..9670ded9 100644
--- a/modules-available/dnbd3/config.json
+++ b/modules-available/dnbd3/config.json
@@ -1,4 +1,7 @@
{
- "category":"main.settings-server",
- "dependencies":["locations","runmode"]
-}
+ "category": "main.settings-server",
+ "dependencies": [
+ "locations",
+ "runmode"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/hooks/main-warning.inc.php b/modules-available/dnbd3/hooks/main-warning.inc.php
index e38048e1..5f8a844f 100644
--- a/modules-available/dnbd3/hooks/main-warning.inc.php
+++ b/modules-available/dnbd3/hooks/main-warning.inc.php
@@ -1,6 +1,6 @@
<?php
-if (Dnbd3::isEnabled()) {
+if (Dnbd3::isEnabled() && User::hasPermission('.dnbd3.access-page')) {
$res = Database::simpleQuery('SELECT s.fixedip, s.lastseen AS dnbd3lastseen, s.errormsg, m.clientip, m.hostname
FROM dnbd3_server s
LEFT JOIN machine m USING (machineuuid)
diff --git a/modules-available/dnbd3/hooks/runmode/config.json b/modules-available/dnbd3/hooks/runmode/config.json
index 5db53f0b..683e0280 100644
--- a/modules-available/dnbd3/hooks/runmode/config.json
+++ b/modules-available/dnbd3/hooks/runmode/config.json
@@ -3,6 +3,7 @@
"configHook": "Dnbd3Util::runmodeConfigHook",
"noSysconfig": true,
"systemdDefaultTarget": "dnbd3-proxy",
- "allowGenericEditor": false,
- "deleteUrlSnippet": "dummyparam="
+ "allowGenericEditor": true,
+ "deleteUrlSnippet": "dummyparam=",
+ "permission": ".dnbd3.configure.proxy"
} \ No newline at end of file
diff --git a/modules-available/dnbd3/inc/dnbd3util.inc.php b/modules-available/dnbd3/inc/dnbd3util.inc.php
index 95b6ffe2..33581b77 100644
--- a/modules-available/dnbd3/inc/dnbd3util.inc.php
+++ b/modules-available/dnbd3/inc/dnbd3util.inc.php
@@ -103,6 +103,7 @@ class Dnbd3Util {
*/
public static function runmodeConfigHook($machineUuid, $mode, $modeData)
{
+ $self = Property::getServerIp();
// Get all directly assigned locations
$res = Database::simpleQuery('SELECT locationid FROM dnbd3_server
INNER JOIN dnbd3_server_x_location USING (serverid)
@@ -124,10 +125,20 @@ class Dnbd3Util {
}
$res = Database::simpleQuery('SELECT startaddr, endaddr FROM subnet WHERE locationid IN (:locs)',
array('locs' => array_values($recursiveLocs)));
+ // Coalesce overlapping ranges
+ $floatIp = ip2long($self); // Float for 32bit php :/
+ if (PHP_INT_SIZE === 4) {
+ $floatIp = (float)sprintf('%u', $floatIp); // Float for 32bit php :/
+ }
+ $ranges = [['startaddr' => $floatIp, 'endaddr' => $floatIp]];
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ settype($row['startaddr'], PHP_INT_SIZE === 4 ? 'float' : 'int');
+ settype($row['endaddr'], PHP_INT_SIZE === 4 ? 'float' : 'int');
+ self::mergeRanges($ranges, $row);
+ }
// Got subnets, build whitelist
- // TODO: Coalesce overlapping ranges
$opt = '';
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($ranges as $row) {
$opt .= ' ' . self::range2Cidr($row['startaddr'], $row['endaddr']);
}
if (!empty($opt)) {
@@ -141,7 +152,6 @@ class Dnbd3Util {
WHERE s.machineuuid <> :uuid OR s.machineuuid IS NULL', array('uuid' => $machineUuid));
$public = array();
$private = array();
- $self = Property::getServerIp();
$public[$self] = $self;
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$ip = $row['fixedip'] ? $row['fixedip'] : $row['clientip'];
@@ -188,13 +198,47 @@ class Dnbd3Util {
*/
private static function range2Cidr($start, $end)
{
- $bin = decbin((int)$start ^ (int)$end);
+ if (PHP_INT_SIZE > 4) {
+ $bin = decbin((int)$start ^ (int)$end);
+ } else {
+ $bin = decbin((int)(float)$start ^ (int)(float)$end);
+ }
if ($bin === '0')
return long2ip($start);
$mask = 32 - strlen($bin);
return long2ip($start) . '/' . $mask;
}
+ private static function mergeRanges(&$ranges, $row)
+ {
+ if ($row['startaddr'] >= $row['endaddr'])
+ return; // Don't even bother
+ foreach (array_keys($ranges) as $key) {
+ if ($row['startaddr'] <= $ranges[$key]['startaddr'] && $row['endaddr'] >= $ranges[$key]['endaddr']) {
+ // Fully dominated
+ unset($ranges[$key]);
+ continue; // Might partially overlap with additional ranges, keep going
+ }
+ if ($ranges[$key]['startaddr'] <= $row['startaddr'] && $ranges[$key]['endaddr'] >= $row['startaddr']) {
+ // $row['startaddr'] lies within existing range
+ if ($ranges[$key]['startaddr'] <= $row['endaddr'] && $ranges[$key]['endaddr'] >= $row['endaddr'])
+ return; // Fully in existing range, do nothing
+ // $row['endaddr'] seems to extend range we're checking against but $row['startaddr'] lies within this range, update and keep going
+ $row['startaddr'] = $ranges[$key]['startaddr'];
+ unset($ranges[$key]);
+ continue;
+ }
+ // Last possibility: $row['startaddr'] is before range, $row['endaddr'] within range
+ if ($ranges[$key]['startaddr'] <= $row['endaddr'] && $ranges[$key]['endaddr'] >= $row['endaddr']) {
+ // $row['startaddr'] must lie before range start, otherwise we'd have hit the case above
+ $row['endaddr'] = $ranges[$key]['endaddr'];
+ unset($ranges[$key]);
+ continue;
+ }
+ }
+ $ranges[] = $row;
+ }
+
public static function defaultRunmodeConfig()
{
return array(
diff --git a/modules-available/dnbd3/lang/de/permissions.json b/modules-available/dnbd3/lang/de/permissions.json
new file mode 100644
index 00000000..15d17336
--- /dev/null
+++ b/modules-available/dnbd3/lang/de/permissions.json
@@ -0,0 +1,8 @@
+{
+ "access-page": "Seite sehen",
+ "configure.external": "Externen Proxy bearbeiten",
+ "configure.proxy": "Automatischen Proxy bearbeiten",
+ "refresh": "Serverliste aktualisieren",
+ "toggle-usage": "Aktivieren\/Deaktivieren",
+ "view.details": "Proxydetails anzeigen"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/de/template-tags.json b/modules-available/dnbd3/lang/de/template-tags.json
index 5406f1b5..22c74b7d 100644
--- a/modules-available/dnbd3/lang/de/template-tags.json
+++ b/modules-available/dnbd3/lang/de/template-tags.json
@@ -10,12 +10,14 @@
"lang_client": "Client",
"lang_clientCount": "Clients",
"lang_clientList": "Liste der Clients",
+ "lang_clients": "Clients",
"lang_clientsByLocation": "Clients nach Raum\/Ort",
"lang_comment": "Kommentar",
+ "lang_complete": "Komplett",
"lang_count": "Anzahl",
"lang_disabled": "Deaktiviert",
"lang_diskFree": "Freier Speicher",
- "lang_dnbd3IntroText": "DNBD3 ist ein verteiltes Speichersystem speziell f\u00fcr die Anforderungen von bwLehrpool. Erst in Verbindung mit mindestens einem Proxy (zus\u00e4tzlich zum Satellitenserver) kann das System seine Geschwindigkeitsvorteile gegen\u00fcber NFS\/CIFS ausspielen. F\u00fcr schlecht angebundene Poolr\u00e4ume empfiehlt sich jeweils ein eigener Proxy-Server.\r\nBitte beachten Sie die Hinweise im Wiki.",
+ "lang_dnbd3IntroText": "DNBD3 ist ein verteiltes Speichersystem speziell f\u00fcr die Anforderungen von bwLehrpool. Erst in Verbindung mit mindestens einem Proxy (zus\u00e4tzlich zum Satellitenserver) kann das System seine Geschwindigkeitsvorteile gegen\u00fcber NFS\/CIFS ausspielen. F\u00fcr schlecht angebundene Poolr\u00e4ume empfiehlt sich jeweils ein eigener Proxy-Server. Bitte beachten Sie die Hinweise im Wiki.",
"lang_dnbd3Management": "DNBD3 Verwaltung",
"lang_dnbd3Status": "DNBD3 Status",
"lang_editProxyHeading": "Proxy-Einstellungen bearbeiten",
@@ -24,11 +26,13 @@
"lang_enterIpOfServer": "Bitte geben Sie die IP-Adresse des hinzuzuf\u00fcgenden Servers ein",
"lang_externalServer": "Externer DNBD3-Server",
"lang_externalServerAdd": "Externen Server hinzuf\u00fcgen",
- "lang_externalServerHelp": "Ein externer Server wird nicht \u00fcber den Satellitenserver konfiguriert und verwaltet. Das Installieren, Einrichten und ggf. Aktualisieren der DNBD3-Serversoftware muss manuell durchgef\u00fchrt werden.\r\nDies bietet mehr Flexibilit\u00e4t bei der Konfiguration und Anpassung, z.B. bei der Verwendung von RAID- oder bcache-Setups, oder wenn der DNBD3-Server auf einer Maschine laufen soll, die noch andere Services bereitstellt.\r\nWeitere Informationen dazu finden Sie im Wiki.",
- "lang_firewallInfo": "Wird ein Proxy auf einen oder mehrere R\u00e4ume beschr\u00e4nkt, werden Clients aus anderen R\u00e4umen diesen Proxy nicht verwenden. Technisch ist der Zugriff aus anderen R\u00e4umen jedoch trotzdem noch m\u00f6glich. Mit aktivieren dieser Option wird der Zugriff aus anderen R\u00e4umen per Firewall verhindert.",
- "lang_firewalled": "Zugriff auf zugewiesene R\u00e4ume beschr\u00e4nken",
+ "lang_externalServerHelp": "Ein externer Server wird nicht \u00fcber den Satellitenserver konfiguriert und verwaltet. Das Installieren, Einrichten und ggf. Aktualisieren der DNBD3-Serversoftware muss manuell durchgef\u00fchrt werden. Dies bietet mehr Flexibilit\u00e4t bei der Konfiguration und Anpassung, z.B. bei der Verwendung von RAID- oder bcache-Setups, oder wenn der DNBD3-Server auf einer Maschine laufen soll, die noch andere Services bereitstellt. Weitere Informationen dazu finden Sie im Wiki.",
+ "lang_firewallInfo": "Wird ein Proxy auf einen oder mehrere R\u00e4ume beschr\u00e4nkt, werden Clients aus anderen R\u00e4umen diesen Proxy nicht verwenden. Technisch ist der Zugriff aus anderen R\u00e4umen jedoch trotzdem noch m\u00f6glich. Mit Aktivieren dieser Option wird der Zugriff aus anderen R\u00e4umen per Firewall verhindert.",
+ "lang_firewalled": "Zugriff zus\u00e4tzlich per Firewall auf zugewiesene R\u00e4ume beschr\u00e4nken",
"lang_flags": "Flags",
"lang_global": "Global",
+ "lang_image": "Image",
+ "lang_imageList": "Image-Liste",
"lang_lastSeen": "Letzte Aktivit\u00e4t",
"lang_latency": "Latenz",
"lang_location": "Ort",
@@ -36,7 +40,9 @@
"lang_manageAccessTo": "Zugriff auf Server festlegen:",
"lang_managedServer": "Automatisch konfigurierter DNBD3-Proxy",
"lang_managedServerAdd": "Automatisch konfigurierten Proxy hinzuf\u00fcgen",
- "lang_managedServerHelp": "Automatisch konfigurierte DNBD3-Proxies booten wie gew\u00f6hnliche bwLehrpool-Clients via PXE \u00fcber den Satelliten-Server. Sobald ein bwLehrpool-Client als DNBD3-Proxy konfiguriert wird, erh\u00e4lt er beim Booten eine gesonderte Konfiguration, sodass er fortan exklusiv als DNBD3-Proxy arbeitet, und nicht mehr als Arbeitsstation zur Verf\u00fcgung steht.\r\nDer Vorteil ist, dass die Konfiguration automatisiert erfolgt, und durch w\u00f6chentliche Reboots sichergestellt wird, dass eventuelle Updates des MiniLinux angewendet werden.\r\nIn diesem Fall legen Sie bitte eine Partition mit der ID 45 auf der Festplatte des Proxy-Servers an; diese wird persistent Behandelt und im Gegensatz zur ID44-Partition nicht beim Booten formatiert. Generell sollte diese Partition so gro\u00df wie m\u00f6glich sein, abh\u00e4ngig von der Anzahl der genutzten VMs. Bei Platzmangel l\u00f6scht der Proxy automatisch die VM, die am l\u00e4ngsten nicht verwendet wurde, um neuen VMs Platz zu machen.\r\nWeitere Informationen dazu finden Sie im Wiki.",
+ "lang_managedServerHelp": "Automatisch konfigurierte DNBD3-Proxies booten wie gew\u00f6hnliche bwLehrpool-Clients via PXE \u00fcber den Satellitenserver. Sobald ein bwLehrpool-Client als DNBD3-Proxy konfiguriert wird, erh\u00e4lt er beim Booten eine gesonderte Konfiguration, sodass er fortan exklusiv als DNBD3-Proxy arbeitet, und nicht mehr als Arbeitsstation zur Verf\u00fcgung steht. Der Vorteil ist, dass die Konfiguration automatisiert erfolgt, und durch w\u00f6chentliche Reboots sichergestellt wird, dass eventuelle Updates des MiniLinux angewendet werden. In diesem Fall legen Sie bitte eine Partition mit der ID 45 auf der Festplatte des Proxy-Servers an; diese wird persistent Behandelt und im Gegensatz zur ID44-Partition nicht beim Booten formatiert. Generell sollte diese Partition so gro\u00df wie m\u00f6glich sein, abh\u00e4ngig von der Anzahl der genutzten VMs. Bei Platzmangel l\u00f6scht der Proxy automatisch die VM, die am l\u00e4ngsten nicht verwendet wurde, um neuen VMs Platz zu machen. Weitere Informationen dazu finden Sie im Wiki.",
+ "lang_manualRefresh": "Jetzt abfragen",
+ "lang_manualRefreshInfo": "Normalerweile werden die in dieser Tabelle angezeigten Daten alle 5 Minuten aktualisiert. Mit diesem Button k\u00f6nnen Sie die Daten sofort aktualisieren.",
"lang_numFails": "Fehler",
"lang_overrideIp": "Zu verwendende IP-Adresse",
"lang_overrideIpInfo": "Normalerweise wird die automatisch per DHCP zugewiesene Adresse auf dem Boot-Interface verwendet. Falls der Proxy mit weiteren Netzwerkkarten ausgestattet ist (die ebenfalls per DHCP konfiguriert werden) kann durch Angabe einer solchen Alternativadresse hier die Verwendung der entsprechenden Karte erzwungen werden.",
@@ -52,9 +58,11 @@
"lang_sessionRx": "Seit Neustart empfangen",
"lang_sessionTx": "Seit Neustart gesendet",
"lang_settings": "Einstellungen",
+ "lang_size": "Gr\u00f6\u00dfe",
"lang_storageSize": "Speichergr\u00f6\u00dfe",
"lang_test": "Testen",
"lang_txTotal": "Gesamt gesendet",
+ "lang_uplink": "Uplink",
"lang_uptime": "Aktuelle Laufzeit",
"lang_wantToDelete": "Wollen Sie diesen Server wirklich entfernen? (Rebooten\/Ausschalten muss in diesem Fall manuell vorgenommen werden)"
} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/en/permissions.json b/modules-available/dnbd3/lang/en/permissions.json
new file mode 100644
index 00000000..112deb94
--- /dev/null
+++ b/modules-available/dnbd3/lang/en/permissions.json
@@ -0,0 +1,8 @@
+{
+ "access-page": "View this page",
+ "configure.external": "Edit external proxy",
+ "configure.proxy": "Edit automatic proxy",
+ "refresh": "Refresh server list",
+ "toggle-usage": "Activate\/Deactivate",
+ "view.details": "Show proxy details"
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/lang/en/template-tags.json b/modules-available/dnbd3/lang/en/template-tags.json
index 81b9d538..932b899a 100644
--- a/modules-available/dnbd3/lang/en/template-tags.json
+++ b/modules-available/dnbd3/lang/en/template-tags.json
@@ -10,8 +10,10 @@
"lang_client": "Client",
"lang_clientCount": "Clients",
"lang_clientList": "List of clients",
+ "lang_clients": "Clients",
"lang_clientsByLocation": "Clients by location",
"lang_comment": "Comment",
+ "lang_complete": "Complete",
"lang_count": "Count",
"lang_disabled": "Disabled",
"lang_diskFree": "Free space",
@@ -25,10 +27,12 @@
"lang_externalServer": "External DNBD3-Server",
"lang_externalServerAdd": "Add external server",
"lang_externalServerHelp": "An external server is not configured and managed by the satellite server. The installation, configuration and update of the DNBD3 software has to be done manually. This is a more flexible approach which is preferable for RAID or bcache setups or if the DNBD3-Server offers additional services. More information in the wiki.",
- "lang_firewallInfo": "If the proxy is restricted to one or more locations, clients from other locations won't use that specific proxy. But technically it's still possible to gain access from other locations. If you activate this setting the access from other locations is blocked with iptables.",
- "lang_firewalled": "Limit access to corresponding locations",
+ "lang_firewallInfo": "If the proxy is restricted to one or more locations, clients from other locations won't use that specific proxy, but technically it's still possible to access this proxy from other locations. If you activate this setting the access from other locations is forcefully blocked using iptables.",
+ "lang_firewalled": "Limit access to corresponding locations via firewall",
"lang_flags": "Flags",
"lang_global": "Global",
+ "lang_image": "Image",
+ "lang_imageList": "Image list",
"lang_lastSeen": "Last seen",
"lang_latency": "Latency",
"lang_location": "Location",
@@ -37,6 +41,8 @@
"lang_managedServer": "Automatically configured DNBD3-Proxy",
"lang_managedServerAdd": "Add automatically configured proxy",
"lang_managedServerHelp": "Automatically configured DNBD3-Proxies will boot like normal bwLehrpool-Clients over PXE and the satellite server. If a client is configured as proxy it will boot with a different configuration and acts exclusively as proxy. The client can therefore not be used as a normal working station.\r\nThe advantage is that you don't need to install or configure anything else. The client will reboot every week to get possible updates ot the minilinux.\r\nIf you want to use this feature, please create a partition with ID 45 on the local hard disk of the proxy server. In contrast to the ID 44 partition which is formated after every reboot, this partition is persistent. As a rule of thumb the partition should be as big as possible. If there is no space left the proxy will delete the VM which hasn't be used for the longest time. More information in the wiki.",
+ "lang_manualRefresh": "Manual refresh",
+ "lang_manualRefreshInfo": "All servers are queried every 5 minutes to update the table below. Hit the refresh button to update the table immediately.",
"lang_numFails": "Errors",
"lang_overrideIp": "IP address to use",
"lang_overrideIpInfo": "Usually the address that the DHCP server assigns to the boot interface of the proxy will be used. If the proxy has multiple interfaces (that also get an address assigned via DHCP) you can specify that address here to enforce their usage instead.",
@@ -52,9 +58,11 @@
"lang_sessionRx": "Received since boot",
"lang_sessionTx": "Sent since boot",
"lang_settings": "Settings",
+ "lang_size": "Size",
"lang_storageSize": "Storage size",
"lang_test": "Test",
"lang_txTotal": "Total sent",
+ "lang_uplink": "Uplink",
"lang_uptime": "Uptime",
"lang_wantToDelete": "Do you really want to delete this server? (Reboot\/Shutdown has to be done manually)"
} \ No newline at end of file
diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php
index 1fa38805..d8dd6cb8 100644
--- a/modules-available/dnbd3/page.inc.php
+++ b/modules-available/dnbd3/page.inc.php
@@ -11,8 +11,10 @@ class Page_Dnbd3 extends Page
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
+
$action = Request::post('action', false, 'string');
if ($action === 'refresh') {
+ User::assertPermission('refresh');
Dnbd3Util::updateServerStatus();
} elseif ($action === 'delserver') {
$this->deleteServer();
@@ -37,6 +39,7 @@ class Page_Dnbd3 extends Page
Message::addError('not-automatic-server', $server['ip']);
return;
}
+ $this->assertPermission($server);
$bgr = Request::post('bgr', false, 'bool');
$firewall = Request::post('firewall', false, 'bool');
$overrideIp = false;
@@ -73,6 +76,7 @@ class Page_Dnbd3 extends Page
private function toggleUsage()
{
+ User::assertPermission('toggle-usage');
$enabled = Request::post('enabled', false, 'bool');
$nfs = Request::post('with-nfs', false, 'bool');
$task = Dnbd3::setEnabled($enabled);
@@ -83,6 +87,7 @@ class Page_Dnbd3 extends Page
private function saveServerLocations()
{
$server = $this->getServerById();
+ $this->assertPermission($server);
$locids = Request::post('location', [], 'array');
if (empty($locids)) {
Database::exec('DELETE FROM dnbd3_server_x_location WHERE serverid = :serverid',
@@ -99,6 +104,7 @@ class Page_Dnbd3 extends Page
private function addServer()
{
+ User::assertPermission('configure.external');
$ip = Request::post('newip', false, 'string');
if ($ip === false) {
Message::addError('main.parameter-missing', 'ip');
@@ -126,6 +132,7 @@ class Page_Dnbd3 extends Page
private function deleteServer()
{
$server = $this->getServerById();
+ $this->assertPermission($server);
if ($server['fixedip'] === '<self>')
return;
if (!is_null($server['machineuuid'])) {
@@ -156,9 +163,10 @@ class Page_Dnbd3 extends Page
private function showServerList()
{
+ User::assertPermission('access-page');
$dynClients = RunMode::getForMode(Page::getModule(), 'proxy', true, true);
$res = Database::simpleQuery('SELECT s.serverid, s.machineuuid, s.fixedip, s.lastseen AS dnbd3lastseen,
- s.uptime, s.totalup, s.totaldown, s.clientcount, s.disktotal, s.diskfree, Count(sxl.locationid) AS locations,
+ s.uptime, s.totalup, s.totaldown, s.clientcount, s.disktotal, s.diskfree, GROUP_CONCAT(sxl.locationid) AS locations,
s.errormsg
FROM dnbd3_server s
LEFT JOIN dnbd3_server_x_location sxl USING (serverid)
@@ -166,8 +174,22 @@ class Page_Dnbd3 extends Page
$servers = array();
$sort = array();
$NOW = time();
+ $externalAllowed = User::hasPermission('configure.external');
+ $locsRunmode = User::getAllowedLocations('configure.proxy');
while ($server = $res->fetch(PDO::FETCH_ASSOC)) {
- if (isset($dynClients[$server['machineuuid']])) {
+ if (!is_null($server['machineuuid'])) {
+ // Auto proxy
+ if (!isset($dynClients[$server['machineuuid']])) {
+ // Not in runmode dnbd3!?
+ if ($NOW - $server['dnbd3lastseen'] > 660) {
+ // Also seems to be down - delete
+ Database::exec('DELETE FROM dnbd3_server WHERE serverid = :serverid',
+ array('serverid' => $server['serverid']));
+ continue;
+ }
+ // Not in runmode but (still?) up -- show
+ $server += ['locationid' => null, 'hostname' => '<invalid>'];
+ }
$server += $dynClients[$server['machineuuid']];
unset($dynClients[$server['machineuuid']]);
}
@@ -195,6 +217,23 @@ class Page_Dnbd3 extends Page
$server['slxOk'] = true;
}
}
+ if (is_null($server['locations'])) {
+ $server['locations'] = 0;
+ } else {
+ $locations = explode(',', $server['locations']);
+ $server['locations'] = count($locations);
+ }
+ // Permission to edit
+ if (is_null($server['machineuuid'])) {
+ if (!$externalAllowed) {
+ $server['edit_disabled'] = 'disabled';
+ }
+ } else {
+ if (!array_key_exists('locationid', $server) || !in_array($server['locationid'], $locsRunmode)) {
+ $server['edit_disabled'] = 'disabled';
+ }
+ }
+ // Array for sorting
if ($server['self']) {
$sort[] = '---';
} else {
@@ -203,66 +242,99 @@ class Page_Dnbd3 extends Page
$servers[] = $server;
}
foreach ($dynClients as $server) {
+ $server['edit_disabled'] = 'disabled';
$servers[] = $server;
$sort[] = '-' . $server['machineuuid'];
- Database::exec('INSERT INTO dnbd3_server (machineuuid) VALUES (:uuid)', array('uuid' => $server['machineuuid']));
+ Database::exec('INSERT IGNORE INTO dnbd3_server (machineuuid) VALUES (:uuid)', array('uuid' => $server['machineuuid']));
}
array_multisort($sort, SORT_ASC, $servers);
- Render::addTemplate('page-serverlist', array(
+ $data = array(
'list' => $servers,
'enabled' => Dnbd3::isEnabled(),
'enabled_checked_s' => Dnbd3::isEnabled() ? 'checked' : '',
'nfs_checked_s' => Dnbd3::hasNfsFallback() ? 'checked' : '',
'rebootcontrol' => Module::isAvailable('rebootcontrol', false)
- ));
+ );
+ Permission::addGlobalTags($data['perms'], null, ['view.details', 'refresh', 'toggle-usage', 'configure.proxy', 'configure.external']);
+ Render::addTemplate('page-serverlist', $data);
}
private function showProxyDetails()
{
+ User::assertPermission('view.details');
$server = $this->getServerById();
Render::addTemplate('page-proxy-header', $server);
- $stats = Dnbd3Rpc::query($server['ip'], 5003,true, true, false, true);
+ $stats = Dnbd3Rpc::query($server['ip'], 5003, true, true, true, true, true, true);
if (!is_array($stats) || !isset($stats['runId'])) {
Message::addError('server-unreachable');
return;
}
- $stats['bytesSent_s'] = Util::readableFileSize($stats['bytesSent']);
- $stats['bytesReceived_s'] = Util::readableFileSize($stats['bytesReceived']);
+ foreach (['bytesSent', 'bytesReceived', 'spaceTotal', 'spaceFree'] as $key) {
+ $stats[$key . '_s'] = Util::readableFileSize($stats[$key]);
+ }
+ if ($stats['spaceTotal'] > 0) {
+ $stats['percentFree'] = ($stats['spaceFree'] / $stats['spaceTotal']) * 100;
+ $stats['percentFree'] = round($stats['percentFree'], $stats['percentFree'] < 10 ? 1 : 0);
+ }
$stats['uptime_s'] = floor($stats['uptime'] / 86400) . 'd ' . gmdate('H:i:s', $stats['uptime']);
+ $stats['tab_config'] = is_string($stats['config']);
+ $stats['tab_altservers'] = is_array($stats['altservers']);
Render::addTemplate('page-proxy-stats', $stats);
- // TODO $images = Dnbd3Rpc::query($server['ip'], 5003,false, false, true);
- $confAlts = Dnbd3Rpc::query($server['ip'], 5003,false, false, false, false, true, true);
+ Render::openTag('div', ['class' => 'tab-content']);
$ips = array();
$sort = array();
foreach ($stats['clients'] as &$c) {
$c['bytesSent_s'] = Util::readableFileSize($c['bytesSent']);
$sort[] = $c['bytesSent'];
- $ips[] = preg_replace('/:\d+$/', '', $c['address']);
+ $ips[preg_replace('/:\d+$/', '', $c['address'])] = true;
}
+ $ips = array_keys($ips);
array_multisort($sort, SORT_DESC, $stats['clients']);
- Render::openTag('div', ['class' => 'row']);
// Config
- if (is_string($confAlts['config'])) {
- Render::addTemplate('page-proxy-config', $confAlts);
+ if (is_string($stats['config'])) {
+ preg_match_all('/^((?<sec>\[.*\])|(?<key>[^=]+)=(?<val>.*)|(?<other>[^\[][^=]*))$/m', $stats['config'], $out, PREG_SET_ORDER);
+ $stats['config'] = [];
+ foreach ($out as $line) {
+ if (!empty($line['sec'])) {
+ $stats['config'][] = ['class1' => 'text-primary', 'text1' => $line['sec']];
+ } elseif (!empty($line['other'])) {
+ $stats['config'][] = ['class1' => 'text-muted', 'text1' => $line['other']];
+ } else {
+ $extra = '';
+ $class2 = 'slx-bold';
+ if (in_array($line['key'], ['serverPenalty', 'clientPenalty'])) {
+ $extra = round($line['val'] / 1000, 1) . 'ms';
+ } elseif (in_array($line['key'], ['uplinkTimeout', 'clientTimeout'])) {
+ $extra = round($line['val'] / 1000, 1) . 's';
+ } elseif (in_array($line['key'], ['maxPayload', 'maxReplicationSize'])) {
+ $extra = Util::readableFilesize($line['val']);
+ } elseif ($line['val'] === 'true') {
+ $class2 .= ' text-success';
+ } elseif ($line['val'] === 'false') {
+ $class2 .= ' text-danger';
+ }
+ $stats['config'][] = ['text1' => $line['key'], 'class2' => $class2, 'text2' => $line['val'] . ' ', 'extra' => $extra];
+ }
+ }
+ Render::addTemplate('page-proxy-config', $stats);
}
- if (is_array($confAlts['altservers'])) {
- foreach ($confAlts['altservers'] as &$as) {
+ if (is_array($stats['altservers'])) {
+ foreach ($stats['altservers'] as &$as) {
$as['rtt'] = round(array_sum($as['rtt']) / count($as['rtt']) / 1000, 2);
}
unset($as);
- Render::addTemplate('page-proxy-altservers', $confAlts);
+ Render::addTemplate('page-proxy-altservers', $stats);
}
- Render::closeTag('div');
- Render::openTag('div', ['class' => 'row']);
// Count locations
- $res = Database::simpleQuery('SELECT locationid, Count(*) AS cnt FROM machine WHERE clientip IN (:ips) GROUP BY locationid', compact('ips'));
+ $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt FROM machine
+ WHERE clientip IN (:ips) AND state IN ('IDLE', 'OCCUPIED') GROUP BY locationid", compact('ips'));
$locCount = Location::getLocationsAssoc();
$locCount[0] = array(
'locationname' => '/',
'depth' => 0,
- 'recCount' => 0,
);
foreach ($locCount as &$loc) {
+ $loc['clientCount'] = 0;
$loc['recCount'] = 0;
}
$showLocs = false;
@@ -281,18 +353,27 @@ class Page_Dnbd3 extends Page
$locCount[$p]['recCount'] += $row['cnt'];
}
}
+ $locCount[0]['recCount'] += $row['cnt'];
}
if ($showLocs) {
- $locCount = array_filter($locCount, function ($v) { return isset($v['keep']); });
- Render::addTemplate('page-proxy-loclist', array('list' => array_values($locCount)));
+ $stats['loclist'] = array_values(array_filter($locCount, function ($v) { return isset($v['keep']); }));
}
Render::addTemplate('page-proxy-clients', $stats);
+ $sort1 = $sort2 = [];
+ foreach ($stats['images'] as &$image) {
+ $image['size_s'] = Util::readableFileSize($image['size']);
+ $sort1[] = $image['users'];
+ $sort2[] = $image['name'];
+ }
+ array_multisort($sort1, SORT_NUMERIC | SORT_DESC, $sort2, SORT_ASC, $stats['images']);
+ Render::addTemplate('page-proxy-images', $stats);
Render::closeTag('div');
}
private function showServerLocationEdit()
{
$server = $this->getServerById();
+ $this->assertPermission($server);
// Get selected ones
$res = Database::simpleQuery('SELECT locationid FROM dnbd3_server_x_location WHERE serverid = :serverid',
array('serverid' => $server['serverid']));
@@ -328,14 +409,14 @@ class Page_Dnbd3 extends Page
Message::addError('main.parameter-missing', 'server');
Util::redirect('?do=dnbd3');
}
- $server = Database::queryFirst('SELECT s.serverid, s.machineuuid, s.fixedip, m.clientip, m.hostname
+ $server = Database::queryFirst('SELECT s.serverid, s.machineuuid, s.fixedip, m.clientip, m.hostname, m.locationid
FROM dnbd3_server s
LEFT JOIN machine m USING (machineuuid)
WHERE s.serverid = :serverId', compact('serverId'));
if ($server === false) {
if (AJAX)
die('Invalid server id');
- Message::addError('server-non-existent', 'server');
+ Message::addError('server-non-existent', $serverId);
Util::redirect('?do=dnbd3');
}
if (!is_null($server['fixedip'])) {
@@ -348,6 +429,15 @@ class Page_Dnbd3 extends Page
return $server;
}
+ private function assertPermission($server)
+ {
+ if (isset($server['machineuuid'])) {
+ User::assertPermission('configure.proxy', $server['locationid'], '?do=dnbd3');
+ } else {
+ User::assertPermission('configure.external', null, '?do=dnbd3');
+ }
+ }
+
/*
* AJAX
*/
@@ -371,6 +461,7 @@ class Page_Dnbd3 extends Page
private function ajaxServerTest()
{
+ User::assertPermission('configure.external');
Header('Content-Type: application/json; charset=utf-8');
$ip = Request::post('ip', false, 'string');
if ($ip === false)
@@ -407,6 +498,7 @@ class Page_Dnbd3 extends Page
echo 'Not automatic server.';
return;
}
+ $this->assertPermission($server);
$rm = RunMode::getForMode(Page::getModule(), 'proxy', false, true);
if (!isset($rm[$server['machineuuid']])) {
echo 'Error: RunMode entry missing.';
@@ -423,23 +515,37 @@ class Page_Dnbd3 extends Page
if (!isset($server['machineuuid'])) {
die('Not automatic server.');
}
- if (!Module::isAvailable('rebootcontrol')) {
- die('No rebootcontrol');
- }
$uuid = $server['machineuuid'];
- $task = RebootControl::reboot([ $uuid ]);
+ $task = Request::any('taskid', false, 'string');
if ($task === false) {
- die('Taskmanager unreachable');
+ $this->assertPermission($server);
+ if (!Module::isAvailable('rebootcontrol')) {
+ die('No rebootcontrol');
+ }
+ $task = RebootControl::reboot([$uuid]);
+ if ($task === false) {
+ die('Taskmanager unreachable');
+ }
}
- $task = Taskmanager::waitComplete($task, 2000);
- if (is_array($task) && isset($task['data']) && isset($task['data']['clientStatus']) && isset($task['data']['clientStatus'][$uuid])) {
- $status = $task['data']['clientStatus'][$uuid];
+ $task = Taskmanager::waitComplete($task, 1000);
+ if (is_array($task) && isset($task['data']['clientStatus'][$uuid])) {
+ $status = [
+ 'rebootStatus' => $task['data']['clientStatus'][$uuid],
+ 'taskStatus' => $task['statusCode'],
+ 'taskId' => $task['id'],
+ ];
if (!empty($task['data']['error'])) {
- $status .= "\n --- \n" . $task['data']['error'];
+ $status['error'] = $task['data']['error'];
}
- die($status);
+ } else {
+ $status = [
+ 'rebootStatus' => 'FAILURE',
+ 'taskStatus' => 'FAILURE',
+ 'taskId' => $task['id'],
+ ];
}
- die('Unknown :-(');
+ Header('Content-Type: application/json; charset=utf-8');
+ die(json_encode($status));
}
}
diff --git a/modules-available/dnbd3/permissions/permissions.json b/modules-available/dnbd3/permissions/permissions.json
new file mode 100644
index 00000000..77a72d62
--- /dev/null
+++ b/modules-available/dnbd3/permissions/permissions.json
@@ -0,0 +1,20 @@
+{
+ "access-page": {
+ "location-aware": false
+ },
+ "toggle-usage": {
+ "location-aware": false
+ },
+ "refresh": {
+ "location-aware": false
+ },
+ "view.details": {
+ "location-aware": false
+ },
+ "configure.proxy": {
+ "location-aware": true
+ },
+ "configure.external": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/dnbd3/templates/page-proxy-altservers.html b/modules-available/dnbd3/templates/page-proxy-altservers.html
index 00a884cc..d2e520f9 100644
--- a/modules-available/dnbd3/templates/page-proxy-altservers.html
+++ b/modules-available/dnbd3/templates/page-proxy-altservers.html
@@ -1,11 +1,11 @@
-<div class="col-md-6">
+<div role="tabpanel" class="tab-pane" id="tab-altservers">
<h2>{{lang_altservers}}</h2>
<table class="table table-condensed">
<tr>
- <th>{{lang_proxyServerTHead}}</th>
- <th>{{lang_numFails}}</th>
- <th class="text-right">{{lang_latency}}</th>
- <th>{{lang_flags}}</th>
+ <th class="slx-smallcol">{{lang_proxyServerTHead}}</th>
+ <th class="slx-smallcol">{{lang_numFails}}</th>
+ <th class="text-right slx-smallcol">{{lang_latency}}</th>
+ <th class="slx-smallcol">{{lang_flags}}</th>
<th>{{lang_comment}}</th>
</tr>
{{#altservers}}
@@ -21,7 +21,7 @@
{{rtt}}&thinsp;ms
{{/isClientOnly}}
</td>
- <td>
+ <td class="text-nowrap">
{{#isClientOnly}}
[CO]
{{/isClientOnly}}
diff --git a/modules-available/dnbd3/templates/page-proxy-clients.html b/modules-available/dnbd3/templates/page-proxy-clients.html
index 9e7cec4c..6733a056 100644
--- a/modules-available/dnbd3/templates/page-proxy-clients.html
+++ b/modules-available/dnbd3/templates/page-proxy-clients.html
@@ -1,20 +1,53 @@
-<div class="col-md-6">
- <h2>{{lang_clientList}}</h2>
+<div role="tabpanel" class="tab-pane active" id="tab-clients">
+ <div class="row">
+ <div class="col-md-6">
+ {{#loclist.0}}
+ <h2>{{lang_clientsByLocation}}</h2>
- <table class="table table-condensed">
- <tr>
- <th>{{lang_client}}</th>
- <th class="text-right">{{lang_bytesSent}}</th>
- </tr>
- {{#clients}}
- <tr>
- <td>
- {{address}}
- </td>
- <td data-sort="int" data-sort-value="{{bytesSent}}" class="text-right">
- {{bytesSent_s}}
- </td>
- </tr>
- {{/clients}}
- </table>
+ <table class="table table-condensed">
+ <tr>
+ <th>{{lang_location}}</th>
+ <th class="text-right">{{lang_count}}</th>
+ <th class="text-right">{{lang_recursiveCount}}</th>
+ </tr>
+ {{#loclist}}
+ <tr>
+ <td>
+ {{#depth}}
+ <div style="display:inline-block;width:{{depth}}em"></div>
+ {{/depth}}
+ {{locationname}}
+ </td>
+ <td class="text-right">
+ {{clientCount}}
+ </td>
+ <td class="text-right">
+ {{recCount}}
+ </td>
+ </tr>
+ {{/loclist}}
+ </table>
+ {{/loclist.0}}
+ </div>
+ <div class="col-md-6">
+ <h2>{{lang_clientList}}</h2>
+
+ <table class="table table-condensed">
+ <tr>
+ <th>{{lang_client}}</th>
+ <th class="text-right">{{lang_bytesSent}}</th>
+ </tr>
+ {{#clients}}
+ <tr>
+ <td>
+ {{address}}
+ </td>
+ <td data-sort="int" data-sort-value="{{bytesSent}}" class="text-right">
+ {{bytesSent_s}}
+ </td>
+ </tr>
+ {{/clients}}
+ </table>
+ </div>
+ </div>
</div> \ No newline at end of file
diff --git a/modules-available/dnbd3/templates/page-proxy-config.html b/modules-available/dnbd3/templates/page-proxy-config.html
index adc73a57..f258e030 100644
--- a/modules-available/dnbd3/templates/page-proxy-config.html
+++ b/modules-available/dnbd3/templates/page-proxy-config.html
@@ -1,4 +1,18 @@
-<div class="col-md-6">
+<style>
+.tt { font-family:monospace }
+.tt .eq { margin:0 1ex }
+.tt .usel { user-select:none }
+.tt .usel::before { content: attr(data-con) }
+</style>
+<div role="tabpanel" class="tab-pane" id="tab-config">
<h2>{{lang_proxyConfig}}</h2>
- <pre>{{config}}</pre>
-</div> \ No newline at end of file
+ <div class="well tt" style="font-family:monospace">
+ {{#config}}
+ <span class="{{class1}}">{{text1}}</span>{{#text2}}<span class="eq">=</span>{{/text2}}<span class="{{class2}}">{{text2}}</span>
+ {{#extra}}
+ <span class="text-muted usel" data-con=" ; {{extra}}"></span>
+ {{/extra}}
+ <br>
+ {{/config}}
+ </div>
+</div>
diff --git a/modules-available/dnbd3/templates/page-proxy-header.html b/modules-available/dnbd3/templates/page-proxy-header.html
index 6f3f1b7f..7f3418cc 100644
--- a/modules-available/dnbd3/templates/page-proxy-header.html
+++ b/modules-available/dnbd3/templates/page-proxy-header.html
@@ -1 +1,2 @@
-<h1>{{ip}}</h1> \ No newline at end of file
+<h1>{{ip}}</h1>
+
diff --git a/modules-available/dnbd3/templates/page-proxy-images.html b/modules-available/dnbd3/templates/page-proxy-images.html
new file mode 100644
index 00000000..7e30de20
--- /dev/null
+++ b/modules-available/dnbd3/templates/page-proxy-images.html
@@ -0,0 +1,31 @@
+<div role="tabpanel" class="tab-pane" id="tab-images">
+ <h2>{{lang_imageList}}</h2>
+ <table class="table table-condensed">
+ <tr>
+ <th>{{lang_image}}</th>
+ <th class="text-right slx-smallcol">{{lang_clients}}</th>
+ <th class="text-right slx-smallcol">{{lang_size}}</th>
+ <th class="text-right slx-smallcol">{{lang_complete}}</th>
+ <th class="slx-smallcol">{{lang_uplink}}</th>
+ </tr>
+ {{#images}}
+ <tr>
+ <td class="text-nowrap">
+ {{name}}:{{rid}}
+ </td>
+ <td class="text-right text-nowrap">
+ {{users}}
+ </td>
+ <td class="text-right text-nowrap">
+ {{size_s}}
+ </td>
+ <td class="text-right text-nowrap">
+ {{complete}}&thinsp;%
+ </td>
+ <td class="text-nowrap">
+ {{uplinkServer}}
+ </td>
+ </tr>
+ {{/images}}
+ </table>
+</div> \ No newline at end of file
diff --git a/modules-available/dnbd3/templates/page-proxy-loclist.html b/modules-available/dnbd3/templates/page-proxy-loclist.html
deleted file mode 100644
index 67c90683..00000000
--- a/modules-available/dnbd3/templates/page-proxy-loclist.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<div class="col-md-6">
- <h2>{{lang_clientsByLocation}}</h2>
-
- <table class="table table-condensed">
- <tr>
- <th>{{lang_location}}</th>
- <th class="text-right">{{lang_count}}</th>
- <th class="text-right">{{lang_recursiveCount}}</th>
- </tr>
- {{#list}}
- <tr>
- <td>
- {{#depth}}
- <div style="display:inline-block;width:{{depth}}em"></div>
- {{/depth}}
- {{locationname}}
- </td>
- <td class="text-right">
- {{clientCount}}
- </td>
- <td class="text-right">
- {{recCount}}
- </td>
- </tr>
- {{/list}}
- </table>
-</div> \ No newline at end of file
diff --git a/modules-available/dnbd3/templates/page-proxy-stats.html b/modules-available/dnbd3/templates/page-proxy-stats.html
index e7811028..a866903c 100644
--- a/modules-available/dnbd3/templates/page-proxy-stats.html
+++ b/modules-available/dnbd3/templates/page-proxy-stats.html
@@ -1,9 +1,27 @@
<div class="panel panel-default">
<div class="panel-body">
- {{lang_sessionTx}}: <b>{{bytesSent_s}}</b>
- ––
- {{lang_sessionRx}}: <b>{{bytesReceived_s}}</b>
- ––
- {{lang_uptime}}: <b>{{uptime_s}}</b>
+ <div>
+ {{lang_sessionTx}}: <b>{{bytesSent_s}}</b>
+ ––
+ {{lang_sessionRx}}: <b>{{bytesReceived_s}}</b>
+ ––
+ {{lang_uptime}}: <b>{{uptime_s}}</b>
+ </div>
+ <div>
+ {{lang_storageSize}}: <b>{{spaceTotal_s}}</b>
+ ––
+ {{lang_diskFree}}: <b>{{spaceFree_s}} ({{percentFree}}&thinsp;%)</b>
+ </div>
</div>
-</div> \ No newline at end of file
+</div>
+
+<ul class="nav nav-tabs text-center" role="tablist">
+ {{#tab_config}}
+ <li role="presentation"><a href="#tab-config" role="tab" data-toggle="tab">{{lang_proxyConfig}}</a></li>
+ {{/tab_config}}
+ <li role="presentation" class="active"><a href="#tab-clients" role="tab" data-toggle="tab">{{lang_clientList}}</a></li>
+ <li role="presentation"><a href="#tab-images" role="tab" data-toggle="tab">{{lang_imageList}}</a></li>
+ {{#tab_altservers}}
+ <li role="presentation"><a href="#tab-altservers" role="tab" data-toggle="tab">{{lang_altservers}}</a></li>
+ {{/tab_altservers}}
+</ul> \ No newline at end of file
diff --git a/modules-available/dnbd3/templates/page-serverlist.html b/modules-available/dnbd3/templates/page-serverlist.html
index c5905dcd..65e4d6ea 100644
--- a/modules-available/dnbd3/templates/page-serverlist.html
+++ b/modules-available/dnbd3/templates/page-serverlist.html
@@ -15,14 +15,14 @@
<form method="post" action="?do=dnbd3">
<input type="hidden" name="token" value="{{token}}">
<div class="checkbox">
- <input id="enable-dnbd3" type="checkbox" name="enabled" {{enabled_checked_s}}>
+ <input id="enable-dnbd3" type="checkbox" name="enabled" {{enabled_checked_s}} {{perms.toggle-usage.disabled}}>
<label for="enable-dnbd3">{{lang_enableDnbd3}}</label>
</div>
<div class="checkbox">
- <input id="allow-nfs" type="checkbox" name="with-nfs" {{nfs_checked_s}}>
+ <input id="allow-nfs" type="checkbox" name="with-nfs" {{nfs_checked_s}} {{perms.toggle-usage.disabled}}>
<label for="allow-nfs">{{lang_allowNfsFallback}}</label>
</div>
- <button type="submit" name="action" value="toggle-usage" class="btn btn-success">
+ <button type="submit" name="action" value="toggle-usage" class="btn btn-success" {{perms.toggle-usage.disabled}}>
<span class="glyphicon glyphicon-floppy-disk"></span>
{{lang_save}}
</button>
@@ -36,7 +36,10 @@
<input type="hidden" name="action" value="refresh">
<h2>
{{lang_serverList}}
- <button id="refbtn" type="submit" class="btn btn-default"><span class="glyphicon glyphicon-refresh"></span></button>
+ <button id="refbtn" type="submit" class="btn btn-default" {{perms.refresh.disabled}} title="{{lang_manualRefreshInfo}}">
+ <span class="glyphicon glyphicon-refresh"></span>
+ {{lang_manualRefresh}}
+ </button>
</h2>
</form>
@@ -78,14 +81,18 @@
</td>
<td class="{{#self}}slx-bold{{/self}}">
{{#machineuuid}}
- <a class="pull-right btn btn-default btn-xs" href="?do=Statistics&uuid={{machineuuid}}">
+ <a class="pull-right btn btn-default btn-xs" href="?do=statistics&uuid={{machineuuid}}">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{{/machineuuid}}
+ {{^perms.view.details.disabled}}
<a href="?do=dnbd3&amp;show=proxy&amp;server={{serverid}}">
+ {{/perms.view.details.disabled}}
{{fixedip}}
<span class="small">{{clientip}}</span>
+ {{^perms.view.details.disabled}}
</a>
+ {{/perms.view.details.disabled}}
<div class="small">{{hostname}}</div>
</td>
<td data-sort="int" data-sort-default="desc" data-sort-value="{{disktotal}}">
@@ -123,7 +130,7 @@
{{#locations}}
{{locations}}
{{/locations}}
- <a href="?do=dnbd3&amp;show=locations&amp;server={{serverid}}" class="btn btn-default btn-xs">
+ <a href="?do=dnbd3&amp;show=locations&amp;server={{serverid}}" class="btn btn-default btn-xs {{edit_disabled}}">
<span class="glyphicon glyphicon-map-marker"></span>
</a>
{{/self}}
@@ -132,17 +139,19 @@
{{#machineuuid}}
{{#rebootcontrol}}
<button class="btn btn-warning btn-xs reboot-btn" type="button" data-id="{{serverid}}"
- data-toggle="modal" data-target="#server-reboot-modal" title="{{lang_reboot}}">
+ data-toggle="modal" data-target="#server-reboot-modal" title="{{lang_reboot}}"
+ {{edit_disabled}}>
<span class="glyphicon glyphicon-repeat"></span>
</button>
{{/rebootcontrol}}
<button class="btn btn-default btn-xs edit-btn" type="button" data-id="{{serverid}}"
- data-toggle="modal" data-target="#server-edit-modal" title="{{lang_settings}}">
+ data-toggle="modal" data-target="#server-edit-modal" title="{{lang_settings}}"
+ {{edit_disabled}}>
<span class="glyphicon glyphicon-cog"></span>
</button>
{{/machineuuid}}
{{^self}}
- <button class="btn btn-danger btn-xs" name="server" value="{{serverid}}"
+ <button class="btn btn-danger btn-xs" name="server" value="{{serverid}}" {{edit_disabled}}
onclick="return confirm('{{lang_wantToDelete}}')" title="{{lang_delete}}">
<span class="glyphicon glyphicon-trash"></span>
</button>
@@ -156,7 +165,7 @@
<div class="btn-toolbar pull-right">
<div class="btn-group">
- <button type="button" class="btn btn-success" data-toggle="modal" data-target="#add-modal">
+ <button type="button" class="btn btn-success" data-toggle="modal" data-target="#add-modal" {{perms.configure.external.disabled}}>
<span class="glyphicon glyphicon-plus"></span>
{{lang_externalServerAdd}}
</button>
@@ -165,7 +174,7 @@
</button>
</div>
<div class="btn-group">
- <a class="btn btn-success" href="?do=runmode&amp;module=dnbd3&amp;modeid=proxy&amp;redirect=?do=dnbd3">
+ <a class="btn btn-success {{perms.configure.proxy.disabled}}" href="?do=runmode&amp;module=dnbd3&amp;modeid=proxy&amp;redirect=?do=dnbd3">
<span class="glyphicon glyphicon-plus"></span>
{{lang_managedServerAdd}}
</a>
@@ -380,20 +389,32 @@ document.addEventListener('DOMContentLoaded', function () {
}
$t.html('<span class="glyphicon glyphicon-refresh slx-rotation"></span>');
var sid = rebootServerId;
+ var taskId = false;
+ var lastText;
var query = function() {
+ data = {"token": TOKEN, "action": "reboot", "server": sid};
+ if (taskId !== false) data['taskid'] = taskId;
$.ajax({
- "data": {"token": TOKEN, "action": "reboot", "server": sid},
+ "data": data,
"method": "POST",
- "dataType": "text",
+ "dataType": "json",
"url": "?do=dnbd3"
}).done(function (data) {
- $t.text(data);
- if (data.indexOf('REBOOTING') !== -1 || data.indexOf('CONNECTING') !== -1) {
+ if (!data || !data.taskId) return;
+ if (taskId === false) taskId = data.taskId;
+ if (data.error) data.rebootStatus += ' (' + data.error + ')';
+ if (data.rebootStatus !== lastText) {
+ $t.empty().text(data.rebootStatus);
+ }
+ if (data.taskStatus === 'TASK_PROCESSING' || data.taskStatus === 'TASK_WAITING') {
setTimeout(query, 5000);
- $t.append($('<span class="glyphicon glyphicon-refresh slx-rotation"></span>'));
+ if (data.rebootStatus !== lastText) {
+ $t.append($('<span class="glyphicon glyphicon-refresh slx-rotation"></span>'));
+ }
}
+ lastText = data.rebootStatus;
}).fail(function () {
- $.text('Failed');
+ $t.text('Failed');
});
};
query();
diff --git a/modules-available/dozmod/api.inc.php b/modules-available/dozmod/api.inc.php
index 74aaa003..74934dc9 100644
--- a/modules-available/dozmod/api.inc.php
+++ b/modules-available/dozmod/api.inc.php
@@ -17,7 +17,7 @@ if (!Module::isAvailable('locations')) {
define('LIST_URL', CONFIG_DOZMOD_URL . '/vmchooser/list');
define('VMX_URL', CONFIG_DOZMOD_URL . '/vmchooser/lecture');
-$availableRessources = ['list', 'vmx', 'test', 'netrules', 'runscript', 'netshares'];
+$availableRessources = ['list', 'vmx', 'netrules', 'runscript', 'metadata', 'netshares'];
/* BEGIN: A simple caching mechanism ---------------------------- */
@@ -216,6 +216,13 @@ function _getVmData($lecture_uuid, $subResource = false)
/** Caching wrapper around _getVmData() **/
function outputResource($lecture_uuid, $resource)
{
+ if ($resource === 'metadata') {
+ // HACK: config.tgz is compressed, don't use gzip output handler
+ @ob_end_clean();
+ Header('Content-Type: application/gzip');
+ } else {
+ Header('Content-Type: text/plain; charset=utf-8');
+ }
$key = $resource . '_' . $lecture_uuid;
if (cache_has($key)) {
cache_get_passthru($key);
@@ -268,7 +275,8 @@ if ($resource === false) {
}
if (!in_array($resource, $availableRessources)) {
- Util::traceError("unknown resource: $resource");
+ Header('HTTP/1.1 400 Bad Request');
+ die("unknown resource: $resource");
}
$ip = $_SERVER['REMOTE_ADDR'];
diff --git a/modules-available/dozmod/config.json b/modules-available/dozmod/config.json
index 706412d0..110f8b67 100644
--- a/modules-available/dozmod/config.json
+++ b/modules-available/dozmod/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.content"
-}
+ "category": "main.content"
+} \ No newline at end of file
diff --git a/modules-available/dozmod/hooks/main-warning.inc.php b/modules-available/dozmod/hooks/main-warning.inc.php
index ffa87692..1778bb9d 100644
--- a/modules-available/dozmod/hooks/main-warning.inc.php
+++ b/modules-available/dozmod/hooks/main-warning.inc.php
@@ -4,8 +4,10 @@
* Show notification in main window if there are images that should be deleted and are waiting for confirmation
*/
-$res = Database::queryFirst("SELECT Count(*) AS cnt FROM sat.imageversion WHERE deletestate = 'SHOULD_DELETE'", array(), true);
-if (isset($res['cnt']) && $res['cnt'] > 0) {
- Message::addInfo('dozmod.images-pending-delete-exist', true, $res['cnt']);
-}
-unset($res);
+if (User::hasPermission('.dozmod.expiredimages.delete')) {
+ $res = Database::queryFirst("SELECT Count(*) AS cnt FROM sat.imageversion WHERE deletestate = 'SHOULD_DELETE'", array(), true);
+ if (isset($res['cnt']) && $res['cnt'] > 0) {
+ Message::addInfo('dozmod.images-pending-delete-exist', true, $res['cnt']);
+ }
+ unset($res);
+} \ No newline at end of file
diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json
index 60c37927..805472d0 100644
--- a/modules-available/dozmod/lang/de/messages.json
+++ b/modules-available/dozmod/lang/de/messages.json
@@ -3,9 +3,29 @@
"delete-images": "L\u00f6schung: {{0}}",
"dozmod-error": "Fehler bei der Kommunikation mit dem bwLehrpool-Suite server: {{0}}",
"images-pending-delete-exist": "Zur L\u00f6schung markierte VM-Versionen: {{0}}",
+ "ldap-filter-created": "LDAP Filter wurde erfolgreich erstellt",
+ "ldap-filter-deleted": "LDAP Filter wurde erfolgreich gel\u00f6scht",
+ "ldap-filter-id-missing": "Fehlende LDAP Filter ID",
+ "ldap-filter-insert-failed": "LDAP filter konnte der Datenbank nicht hinzugef\u00fcgt werden",
+ "ldap-filter-save-missing-information": "Es fehlen LDAP Filter Informationen",
+ "ldap-filter-saved": "LDAP Filter wurde erfolgreich gespeichert",
+ "ldap-invalid-filter-id": "Ung\u00fcltige LDAP Filter ID",
"mail-config-saved": "Mail-Konfiguration gespeichert",
+ "networkrule-deleted": "Netzwerk-Regel gel\u00f6scht",
+ "networkrule-invalid-direction": "Ung\u00fcltige Richtung: {{0}}",
+ "networkrule-invalid-ruleid": "Nicht-existierende Regel: {{0}}",
+ "networkrule-missing-host": "Fehlende Hostangabe",
+ "networkrule-missing-port": "Fehlende Portangabe",
+ "networkrule-saved": "Netzwerk-Regel gespeichert",
+ "networkshare-deleted": "Netzlaufwerk gel\u00f6scht",
+ "networkshare-invalid-auth-type": "Ung\u00fcltiger Authentifizierungs-Typ: {{0}}",
+ "networkshare-invalid-shareid": "Nicht-existierender Share: {{0}}",
+ "networkshare-missing-path": "Fehlende Pfadangabe",
+ "networkshare-saved": "Netzlaufwerk gespeichert",
"no-expired-images": "Keine Abgelaufenen VM-Versionen",
"nothing-submitted": "Es wurde nichts \u00fcbermittelt",
+ "runscript-invalid-id": "Ung\u00fcltige Script-ID: {{0}}",
+ "runscript-saved": "Script gespeichert",
"runtimelimits-config-saved": "Einstellungen gespeichert",
"templates-saved": "Templates wurden gespeichert",
"timeout": "Zeit\u00fcberschreitung",
diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json
index 02e8c84d..ff4519a7 100644
--- a/modules-available/dozmod/lang/de/module.json
+++ b/modules-available/dozmod/lang/de/module.json
@@ -3,8 +3,12 @@
"page_title": "Verwalten der bwLehrpool-Suite",
"submenu_actionlog": "Aktions-Log",
"submenu_expiredimages": "Abgelaufene VM-Versionen",
+ "submenu_ldapfilters": "LDAP-Filter",
"submenu_mailconfig": "Email-Konfiguration",
- "submenu_runtime": "Limits und Standardwerte",
+ "submenu_networkrules": "Netzwerk-Regeln",
+ "submenu_networkshares": "Netzlaufwerke",
+ "submenu_runscripts": "Startskripte",
+ "submenu_runtimeconfig": "Limits und Standardwerte",
"submenu_templates": "Textbausteine f\u00fcr E-Mails",
"submenu_users": "Benutzer und Berechtigungen"
} \ No newline at end of file
diff --git a/modules-available/dozmod/lang/de/permissions.json b/modules-available/dozmod/lang/de/permissions.json
index 07158a1d..8e743e5c 100644
--- a/modules-available/dozmod/lang/de/permissions.json
+++ b/modules-available/dozmod/lang/de/permissions.json
@@ -1,14 +1,21 @@
{
- "images.delete": "Zur Löschung vorgemerkete Abbilder löschen.",
- "mail.save": "Änderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.",
- "mail.testmail": "Eine Test E-Mail verschicken.",
- "runtimeconfig.save": "Änderungen an der Laufzeit-Konfiguration speichern.",
- "templates.save": "E-Mail Templates speichern.",
- "templates.reset": "E-Mail Templates zurücksetzen.",
- "users.setmail": "E-Mail Benachrichtigungen für einzelne Benutzer aktivieren/deaktivieren.",
- "users.setlogin": "Anmeldungen für einzelne Benutzer aktivieren/deaktivieren.",
- "users.setsu": "Benutzer zu SuperUser ernennen.",
- "users.orglogin": "Anmeldungen für Benutzer von bestimmten Einrichtungen aktivieren/deaktivieren.",
- "log.showuser": "User Data im Aktions-Log anzeigen.",
- "log.showtarget": "Target Data im Aktions-Log anzeigen."
+ "actionlog.view": "Aktions-Log einsehen.",
+ "expiredimages.delete": "Zur L\u00f6schung vorgemerkete Abbilder l\u00f6schen.",
+ "ldapfilters.save": "LDAP Filter speichern.",
+ "ldapfilters.view": "LDAP Filter einsehen.",
+ "mailconfig.save": "\u00c4nderungen an der SMTP-Konfiguration zum Versenden von Mails speichern.",
+ "networkrules.save": "\u00c4nderungen an den Netzwerk-Regeln speichern.",
+ "networkrules.view": "Netzwerk-Regeln einsehen.",
+ "networkshares.save": "\u00c4nderungen an den Netzlaufwerken speichern.",
+ "networkshares.view": "Netzlaufwerke einsehen.",
+ "runscripts.save": "Startkripte erstellen\/bearbeiten.",
+ "runscripts.view": "Startscripte auflisten.",
+ "runtimeconfig.save": "\u00c4nderungen an der Laufzeit-Konfiguration speichern.",
+ "templates.reset": "E-Mail Templates zur\u00fccksetzen.",
+ "templates.save": "E-Mail Templates speichern.",
+ "users.setlogin": "Anmeldungen f\u00fcr einzelne Benutzer aktivieren\/deaktivieren.",
+ "users.setmail": "E-Mail Benachrichtigungen f\u00fcr einzelne Benutzer aktivieren\/deaktivieren.",
+ "users.setorglogin": "Anmeldungen f\u00fcr Benutzer von bestimmten Einrichtungen aktivieren\/deaktivieren.",
+ "users.setsu": "Benutzer zu SuperUser ernennen.",
+ "users.view": "Benutzerliste sehen."
} \ No newline at end of file
diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json
index a1c23d2e..3e000676 100644
--- a/modules-available/dozmod/lang/de/template-tags.json
+++ b/modules-available/dozmod/lang/de/template-tags.json
@@ -1,8 +1,12 @@
{
"lang_actionTarget": "Aktionsziel",
+ "lang_active": "Aktiv",
+ "lang_addRule": "Netzwerk-Regel hinzuf\u00fcgen",
+ "lang_addShare": "Netzlaufwerk hinzuf\u00fcgen",
"lang_allowLoginByDefault": "Login standardm\u00e4\u00dfig erlauben",
"lang_allowLoginDescription": "Wenn diese Option aktiviert ist, k\u00f6nnen sich alle Mitarbeiter der Einrichtung \u00fcber die bwLehrpool-Suite anmelden und VMs\/Veranstaltungen verwalten. Wenn Sie diese Option deaktivieren, m\u00fcssen Sie in der Untersektion \"Benutzer und Berechtigungen\" jeden Benutzer nach dem ersten Loginversuch manuell freischalten.",
"lang_asteriskRequired": "Felder mit (*) sind erforderlich",
+ "lang_authMethod": "Authentifizierung",
"lang_blockCount": "Anzahl Bl\u00f6cke",
"lang_bwlehrpoolsuite": "bwLehrpool-Suite",
"lang_canLoginOrganization": "Nutzer dieser Einrichtung k\u00f6nnen sich am Satelliten anmelden",
@@ -20,7 +24,11 @@
"lang_descriptionPermissionConfig": "Dies sind die Berechtigungen, die ein Benutzer standardm\u00e4\u00dfig f\u00fcr fremde VMs\/Veranstaltungen hat. Sie werden angewandt, wenn der Besitzer keine anderweitigen Berechtigungen w\u00e4hlt.",
"lang_descriptionRuntimeLimits": "Hier k\u00f6nnen Sie verschiedene Limits festlegen, z.B. wie lange eine VM nach dem Hochladen g\u00fcltig ist. Nach Ablauf dieses Zeitraums ist der Verantwortliche gezwungen, eine neue Version der VM hochzuladen. Damit k\u00f6nnen Sie das Ansammeln nicht mehr ben\u00f6tigter VMs eind\u00e4mmen. Weiterhin k\u00f6nnen Sie die maximale Anzahl gleichzeitiger Transfers pro Benutzer einschr\u00e4nken.\r\n\r\nVer\u00e4nderte Einstellungen wirken sich nicht auf bereits bestehende VMs aus.",
"lang_description_delete_images": "Diese Liste zeigt VMs, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.",
+ "lang_direction": "Richtung",
"lang_dozmodLogHeading": "bwLehrpool-Suite Aktionslog",
+ "lang_editNetworkrule": "Netzwerk-Regel bearbeiten",
+ "lang_editNetworkshare": "Netzlaufwerk bearbeiten",
+ "lang_editScript": "Startscript bearbeiten",
"lang_email": "EMail",
"lang_emailNotifications": "EMail-Benachrichtigungen aktiviert",
"lang_error": "Fehler",
@@ -30,50 +38,85 @@
"lang_hasNewer": "Neuere Version existiert",
"lang_hash": "Hash",
"lang_heading": "Zu l\u00f6schende VM-Versionen",
+ "lang_hidden": "Versteckt",
"lang_host": "Host",
"lang_image": "VM",
"lang_lastEditor": "Zuletzt bearbeitet von",
"lang_lastLogin": "Letzte Anmeldung",
"lang_latestVersion": "Neuste Version",
+ "lang_ldapFilterAdd": "LDAP-Filter hinzuf\u00fcgen",
+ "lang_ldapFilterAttribute": "Attribut",
+ "lang_ldapFilterDeleteConfirmation": "Wollen Sie diesen LDAP-Filter wirklich l\u00f6schen?",
+ "lang_ldapFilterDescription": "Dies sind die Filter, die ein Benutzer in der bwLehrpool-Suite Veranstaltungen hinzuf\u00fcgen kann.",
+ "lang_ldapFilterEdit": "LDAP-Filter bearbeiten",
+ "lang_ldapFilterName": "Filtername",
+ "lang_ldapFilterValue": "Wert",
+ "lang_ldapfilters": "LDAP-Filter",
+ "lang_ldapfiltersIntro": "Hier k\u00f6nnen Sie Vorgaben f\u00fcr veranstaltungsspezifische LDAP-Filter machen. LDAP-Filter sind einfache Attributsfilter, die clientseitig Anwendung finden. Die hier definierten Filter werden in der bwLehrpool-Suite als Vorschl\u00e4ge aufgelistet und k\u00f6nnen mittels Checkbox aktiviert werden. Alternativ k\u00f6nnen in der bwLehrpool-Suite auch eigene Filter angelegt werden.",
"lang_lecture": "Veranstaltung",
"lang_lecturePermissionAdmin": "Administration",
"lang_lecturePermissionEdit": "Bearbeiten",
"lang_loadDefaults": "Alle Texte auf Auslieferungszustand zur\u00fccksetzen",
+ "lang_loggedInUser": "Angemeldeter Nutzer",
"lang_mailConfig": "SMTP-Konfiguration zum Versenden von Mails",
- "lang_mailConfigHeadline": "EMail-Konfiguration",
"lang_mailDescription": "F\u00fcllen Sie die folgenden Felder aus, wenn sie m\u00f6chten, dass Dozierende per Mail benachrichtigt werden, falls eine von ihnen genutzte oder erstellte VM oder Veranstaltung abl\u00e4uft. Um diese Funktion zu deaktivieren, lassen Sie eines der mit (*) gekennzeichneten Felder leer. Wenn das hier angegebene E-Mail-Konto nur zum Versenden von Mails genutzt wird, sollten Sie einen Auto-Responder einrichten f\u00fcr den Fall, dass ein Dozierender auf eine der automatisch generierten Mails antwortet (bzw. eine explizit angegebene Reply-To Adresse ignoriert).",
"lang_mailTemplates": "E-Mail Templates",
"lang_maxImageValidity": "G\u00fcltigkeitsdauer neuer VM-Versionen (Tage)",
"lang_maxLectureVisibility": "Sp\u00e4testes Enddatum einer Veranstaltung (Tage in der Zukunft)",
"lang_maxLocationsPerLecture": "Max. explizite Orte pro Veranstaltung",
"lang_maxTransfers": "Maximale Zahl gleichzeitiger Up-\/Downloads pro Benutzer",
+ "lang_minimized": "Minimiert",
"lang_miscOptions": "Verschiedene Einstellungen",
"lang_modified": "Modifiziert",
+ "lang_name": "Name",
+ "lang_networkrules": "Netzwerk-Regeln",
+ "lang_networkrulesIntro": "Hier k\u00f6nnen Sie vordefinierte Regelsets f\u00fcr das Firewalling verwalten. Nutzer der bwLehrpool-Suite k\u00f6nnen auf diese Regelsets zur\u00fcckgreifen, um den Netzwerkzugriff ihrer Veranstaltungen einzuschr\u00e4nken.",
+ "lang_networkshares": "Netzlaufwerke",
+ "lang_networksharesIntro": "Hier k\u00f6nnen Sie vordefinierte Netzlaufwerke anlegen, die den Nutzern der bwLehrpool-Suite zur Auswahl gestellt werden. Es ist den Nutzern der bwLehrpool-Suite weiterhin m\u00f6glich, komplett eigene Netzwerkfreigaben zu definieren. Die Angaben hier sollen lediglich das Hinzuf\u00fcgen h\u00e4ufig genutzter Laufwerke vereinfachen, bzw. das \u00c4ndern eines Netzwerkpfades vereinfachen, da in diesem Fall nur der Zentrale Eintrag hier angepasst werden muss, und nicht mehr wie zuvor jede Veranstaltung einzeln.",
+ "lang_none": "(Keiner)",
+ "lang_normal": "Normal",
"lang_organization": "Einrichtung",
- "lang_organizationList": "Liste der Einrichtungen",
"lang_organizationListHeader": "Nutzungsrechte f\u00fcr den Satelliten festlegen",
"lang_os": "Betriebssystem",
"lang_owner": "Besitzer",
- "lang_passwordplaceholder": "SMTP Passwort",
+ "lang_passwordplaceholder": "SMTP-Passwort",
+ "lang_path": "Pfad",
"lang_placeholders": "Platzhalter",
"lang_port": "Port",
+ "lang_printer": "Drucker",
"lang_reallyResetTemplates": "Sind Sie sicher, dass Sie alle Texte l\u00f6schen und auf die Standardwerte zur\u00fccksetzen wollen?",
"lang_replaceWithOriginal": "Originaltext in Textbox laden",
"lang_replyTo": "Reply-To Adresse",
+ "lang_ruleDeleteConfirm": "Soll dieses Regelset wirklich gel\u00f6scht werden?",
+ "lang_runScriptAdd": "Skript hinzuf\u00fcgen",
+ "lang_runScriptDeleteConfirmation": "Skript wirklich l\u00f6schen?",
"lang_runtimeConfig": "Laufzeit-Konfiguration",
- "lang_runtimeConfigHeadline": "Laufzeit-Konfiguration",
"lang_runtimeConfigLimits": "Beschr\u00e4nkungen",
+ "lang_scriptContent": "Skriptinhalt",
+ "lang_scriptExtension": "Dateinamenerweiterung",
+ "lang_scriptExtensionHead": "Erweiterung",
+ "lang_scriptIsGlobal": "Skript ist global, wird in jeder Veranstaltung ausgef\u00fchrt",
+ "lang_scriptIsGlobalHead": "Global",
+ "lang_scriptIsPredefined": "Skript ist ein vordefiniertes Skript, das in der bwLehrpool-Suite zur Auswahl steht",
+ "lang_scriptPassCredentials": "Benutzername\/Passwort an dieses Skript \u00fcbergeben",
+ "lang_scriptPassCredentialsHead": "User\/Pass",
+ "lang_scriptVisibility": "Anzeigemodus",
+ "lang_scriptVisibilityHead": "Anzeige",
+ "lang_scriptsHead": "Startskripte f\u00fcr Virtuelle Umgebungen",
+ "lang_scriptsIntro": "Hier k\u00f6nnen Sie Startskripte definieren, die entweder global bei jedem Start einer Veranstaltung ausgef\u00fchrt werden, oder den Nutzerinnen der bwLehrpool-Suite zur Vorauswahl zur Verf\u00fcgung gestellt werden.",
"lang_senderAddress": "Absenderadresse",
"lang_senderName": "Absender Anzeigename",
+ "lang_shareDeleteConfirm": "Wollen Sie dieses Netzlaufwerk wirklich l\u00f6schen?",
"lang_size": "Gr\u00f6\u00dfe",
"lang_spaceWastedDuplication": "Potentiell durch mehrfach vorkommende Bl\u00f6cke belegter Speicherplatz",
+ "lang_specificUser": "Spezifischer Nutzer",
"lang_ssl": "SSL-Modus",
"lang_sslExplicit": "Explizites SSL (\"STARTTLS\")",
"lang_sslImplicit": "Implizites SSL",
"lang_sslNone": "Kein SSL",
- "lang_subHeading": "Images, die abgelaufen oder besch\u00e4digt sind",
"lang_superUser": "Ist SuperUser (darf alle Veranstaltungen und VMs bearbeiten\/l\u00f6schen)",
"lang_system": "System",
+ "lang_target": "Ziel",
"lang_template": "Template",
"lang_templatePageDescription": "Hier k\u00f6nnen Sie die Textbausteine bearbeiten, aus denen die Mails generiert werden, die der bwLehrpool-Server bez\u00fcglich Virtueller Maschinen und Veranstaltungen versendet. Diese Funktionalit\u00e4t unterst\u00fctzt zur Zeit keine Internationalisierung.",
"lang_test": "Test-Mail senden",
@@ -83,10 +126,9 @@
"lang_updateTime": "Letzte Bearbeitung",
"lang_user": "Benutzername",
"lang_userId": "Benutzer-ID",
- "lang_userList": "Benutzerliste",
"lang_userListDescription": "Hier k\u00f6nnen Sie individuelle Nutzer zu \"Super-Usern\" machen. Diese haben in der bwLehrpool-Suite auf alle Veranstaltungen und VMs Vollzugriff, unabh\u00e4ngig von den gesetzten Berechtigungen. Au\u00dferdem k\u00f6nnen Sie hier Benutzer vom Zugriff mittels der bwLehrpool-Suite ausschlie\u00dfen.",
"lang_userListHeader": "Dem Satelliten bekannte Benutzer",
- "lang_usernameplaceholder": "SMTP Benutzername",
+ "lang_usernameplaceholder": "SMTP-Benutzername",
"lang_version": "Version vom",
"lang_when": "Wann"
-}
+} \ No newline at end of file
diff --git a/modules-available/dozmod/lang/en/messages.json b/modules-available/dozmod/lang/en/messages.json
index 6d7ea0ac..2d813efc 100644
--- a/modules-available/dozmod/lang/en/messages.json
+++ b/modules-available/dozmod/lang/en/messages.json
@@ -3,9 +3,29 @@
"delete-images": "Delete: {{0}}",
"dozmod-error": "Error communicating with the bwLehrpool-Suite server: {{0}}",
"images-pending-delete-exist": "VMs marked for deletion: {{0}}",
+ "ldap-filter-created": "LDAP filter was successfully created",
+ "ldap-filter-deleted": "LDAP filter successfully deleted",
+ "ldap-filter-id-missing": "LDAP filter id was missing",
+ "ldap-filter-insert-failed": "LDAP filter could not be inserted into the database",
+ "ldap-filter-save-missing-information": "LDAP filter information is missing",
+ "ldap-filter-saved": "Successfully modified LDAP filter",
+ "ldap-invalid-filter-id": "Invalid LDAP filter id",
"mail-config-saved": "Mail config saved",
+ "networkrule-deleted": "Network rule deleted",
+ "networkrule-invalid-direction": "Invalid direction: {{0}}",
+ "networkrule-invalid-ruleid": "Invalid rule id: {{0}}",
+ "networkrule-missing-host": "Missing host",
+ "networkrule-missing-port": "Missing port",
+ "networkrule-saved": "Network rule saved",
+ "networkshare-deleted": "Network share deleted",
+ "networkshare-invalid-auth-type": "Invalid auth type: {{0}}",
+ "networkshare-invalid-shareid": "Invalid share id: {{0}}",
+ "networkshare-missing-path": "Missing network path",
+ "networkshare-saved": "Network share saved",
"no-expired-images": "No expired VMs",
"nothing-submitted": "There was nothing submitted",
+ "runscript-invalid-id": "Invalid script id: {{0}}",
+ "runscript-saved": "Script has been saved",
"runtimelimits-config-saved": "Configuration saved successfully",
"templates-saved": "Templates saved successfully",
"timeout": "Timeout",
diff --git a/modules-available/dozmod/lang/en/module.json b/modules-available/dozmod/lang/en/module.json
index 17a2b838..5bcee464 100644
--- a/modules-available/dozmod/lang/en/module.json
+++ b/modules-available/dozmod/lang/en/module.json
@@ -3,8 +3,12 @@
"page_title": "Manage the bwLehrpool-Suite",
"submenu_actionlog": "action log",
"submenu_expiredimages": "Expired VM versions",
+ "submenu_ldapfilters": "LDAP filters",
"submenu_mailconfig": "email configuration",
- "submenu_runtime": "limits and defaults",
+ "submenu_networkrules": "Network Rules",
+ "submenu_networkshares": "Network Shares",
+ "submenu_runscripts": "Startup scripts",
+ "submenu_runtimeconfig": "limits and defaults",
"submenu_templates": "templates",
"submenu_users": "users and permissions"
} \ No newline at end of file
diff --git a/modules-available/dozmod/lang/en/permissions.json b/modules-available/dozmod/lang/en/permissions.json
index 923a8461..b0fbb071 100644
--- a/modules-available/dozmod/lang/en/permissions.json
+++ b/modules-available/dozmod/lang/en/permissions.json
@@ -1,14 +1,21 @@
{
- "images.delete": "Delete images marked for deletion.",
- "mail.save": "Save SMTP configuration for sending mails.",
- "mail.testmail": "Send a testmail.",
- "runtimeconfig.save": "Save limits and defaults of a runtime configuration.",
- "templates.save": "Save email templates.",
- "templates.reset": "Reset email templates.",
- "users.setmail": "Enable/Disable Email Notification.",
- "users.setlogin": "Enable/Disable Login.",
- "users.setsu": "Set User to superuser.",
- "users.orglogin": "Enalbe/Disable Login for Users from certain organisations.",
- "log.showuser": "Show User Data in Log.",
- "log.showtarget": "Show Target Data in Log."
+ "actionlog.view": "View action log.",
+ "expiredimages.delete": "Delete images marked for deletion.",
+ "ldapfilters.save": "Save LDAP filter.",
+ "ldapfilters.view": "View LDAP filters. ",
+ "mailconfig.save": "Save SMTP configuration for sending mails.",
+ "networkrules.save": "Save network rules.",
+ "networkrules.view": "View network rules.",
+ "networkshares.save": "Save network drives.",
+ "networkshares.view": "View network drives.",
+ "runscripts.save": "Save startup scripts.",
+ "runscripts.view": "View startup scripts.",
+ "runtimeconfig.save": "Save limits and defaults of a runtime configuration.",
+ "templates.reset": "Reset email templates.",
+ "templates.save": "Save email templates.",
+ "users.setlogin": "Enable\/Disable Login.",
+ "users.setmail": "Enable\/Disable Email Notification.",
+ "users.setorglogin": "Enalbe\/Disable Login for Users from certain organisations.",
+ "users.setsu": "Set User to superuser.",
+ "users.view": "View user list."
} \ No newline at end of file
diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json
index f12e4ab8..c33d872b 100644
--- a/modules-available/dozmod/lang/en/template-tags.json
+++ b/modules-available/dozmod/lang/en/template-tags.json
@@ -1,8 +1,12 @@
{
"lang_actionTarget": "Action target",
+ "lang_active": "Active",
+ "lang_addRule": "Add Network Rule",
+ "lang_addShare": "Add Network Share",
"lang_allowLoginByDefault": "Allow all staff members to login and use the bwLehrpool-Suite",
"lang_allowLoginDescription": "If this option is enabled, all members of the organization marked as staff or employee are allowed to login to this server and manage VMs\/courses. Otherwise, new users need to be individually allowed access after their first login attempt by visiting the sub page \"users and permissions\" in this web interface.",
"lang_asteriskRequired": "Fields marked with (*) are required",
+ "lang_authMethod": "Authentication",
"lang_blockCount": "Block count",
"lang_bwlehrpoolsuite": "bwLehrpool-Suite",
"lang_canLoginOrganization": "Users from this organization can login",
@@ -20,60 +24,99 @@
"lang_descriptionPermissionConfig": "These are the default permissions being used for VMs and lectures if the owner does not specify any.",
"lang_descriptionRuntimeLimits": "Here you can define some limits, e.g. how long a newly uploaded VM will be valid. This should make sure that you don't end up with a lot of old, unused VMs over time.\r\n\r\nModified settings won't apply for already existing VMs.",
"lang_description_delete_images": "This is a list of VMs that either expired, or where the disk image is damaged or missing. These VMs are not available in bwLehrpool currently, but you have to manually confirm the deletion of the disk images for safety reasons (clock skew etc.)",
+ "lang_direction": "Direction",
"lang_dozmodLogHeading": "bwLehrpool-Suite action log",
+ "lang_editNetworkrule": "Edit Network Rule",
+ "lang_editNetworkshare": "Edit Network Share",
+ "lang_editScript": "Edit start script",
"lang_email": "E-Mail",
"lang_emailNotifications": "E-Mail notifications enabled",
"lang_error": "Error",
"lang_event": "Event",
"lang_fileSize": "File size",
"lang_followingPlaceholdersUnused": "The following placeholders are not being used",
- "lang_hasNewer": "Newer version exists",
+ "lang_hasNewer": "newer version exists",
"lang_hash": "Hash",
"lang_heading": "Images Marked for Deletion",
+ "lang_hidden": "Hidden",
"lang_host": "Host",
"lang_image": "VM",
"lang_lastEditor": "Edited by",
"lang_lastLogin": "Last login",
"lang_latestVersion": "latest version",
+ "lang_ldapFilterAdd": "Add LDAP filter",
+ "lang_ldapFilterAttribute": "Attribute",
+ "lang_ldapFilterDeleteConfirmation": "Do you really want to delete this LDAP filter.",
+ "lang_ldapFilterDescription": "These are the LDAP filters that can be applied to lectures in the bwLehrpool-Suite.",
+ "lang_ldapFilterEdit": "Edit LDAP filter",
+ "lang_ldapFilterName": "Filter name",
+ "lang_ldapFilterValue": "Value",
+ "lang_ldapfilters": "LDAP filters",
+ "lang_ldapfiltersIntro": "This is the list of predefined lecture filters, based on LDAP attributes. These filters can be applied client side to only show lectures to specific user groups. These predefined filters are shown in the bwLehrpool-Suite when editing a lecture, and can be activated by a simple check box. Users of the bwLehrpool-Suite can either make use of these predefined filters, or add custom ones if desired.",
"lang_lecture": "Lecture",
"lang_lecturePermissionAdmin": "Administrate",
"lang_lecturePermissionEdit": "Edit",
"lang_loadDefaults": "Reset all templates to their defaults",
+ "lang_loggedInUser": "Logged in User",
"lang_mailConfig": "SMTP configuration for sending mails",
- "lang_mailConfigHeadline": "Email Configuration",
"lang_mailDescription": "Fill in the following fields if you want to notify tutors\/professors\/lecturers about expiring VMs and lectures. If you leave one of the required fields blank, the feature will be disabled.",
"lang_mailTemplates": "E-Mail Templates",
"lang_maxImageValidity": "New VM validity (days)",
"lang_maxLectureVisibility": "Max time lecture end date may lie in the future (days)",
"lang_maxLocationsPerLecture": "Max. explicit locations per lecture",
"lang_maxTransfers": "Max concurrent transfers per user",
+ "lang_minimized": "Minimized",
"lang_miscOptions": "Misc options",
"lang_modified": "modified",
+ "lang_name": "Name",
+ "lang_networkrules": "Network Rules",
+ "lang_networkrulesIntro": "This is where you can create predefined rulesets for the lecture-based firewalling. bwLehrpool-Suite users can select those rulesets to limit network access of their lectures.",
+ "lang_networkshares": "Network Shares",
+ "lang_networksharesIntro": "This is the list of predefined network shares. bwLehrpool-Suite users can still add custom network shares to their lectures, however having commonly used network shares as predefined entries should be much more convenient. Another advantage is that changing the path of a network share centrally avoids having to edit a dozen lectures' configuration manually.",
+ "lang_none": "(none)",
+ "lang_normal": "Normal",
"lang_organization": "Organization",
- "lang_organizationList": "List of Organizations",
"lang_organizationListHeader": "Set access permissions for organizations",
"lang_os": "Operating System",
"lang_owner": "Owner",
"lang_passwordplaceholder": "SMTP Password",
+ "lang_path": "Path",
"lang_placeholders": "Placeholders",
"lang_port": "Port",
+ "lang_printer": "Printer",
"lang_reallyResetTemplates": "Are you sure you want to reset all texts to their default values?",
"lang_replaceWithOriginal": "load original text into text box",
"lang_replyTo": "Reply-To address",
+ "lang_ruleDeleteConfirm": "Do you want to delete this ruleset?",
+ "lang_runScriptAdd": "Add run-script",
+ "lang_runScriptDeleteConfirmation": "Do you want to delete this run-script?",
"lang_runtimeConfig": "Limits and Defaults",
- "lang_runtimeConfigHeadline": "Configure Limits and Defaults for bwLehrpool-Suite",
"lang_runtimeConfigLimits": "Limitations",
+ "lang_scriptContent": "Script content",
+ "lang_scriptExtension": "Script extension",
+ "lang_scriptExtensionHead": "Extension",
+ "lang_scriptIsGlobal": "Global script, will execute in every lecture environment",
+ "lang_scriptIsGlobalHead": "Global",
+ "lang_scriptIsPredefined": "Predefined script, selectable by bwLehrpool-Suite users for individual lectures",
+ "lang_scriptPassCredentials": "Pass username and password to this script",
+ "lang_scriptPassCredentialsHead": "User\/Pass",
+ "lang_scriptVisibility": "Display mode",
+ "lang_scriptVisibilityHead": "Display",
+ "lang_scriptsHead": "Run-scripts for lecture environments",
+ "lang_scriptsIntro": "Here you can define scripts that will either forcefully run at startup of a lecture, or are selectable by bwLehrpool-Suite users.",
"lang_senderAddress": "Sender address",
"lang_senderName": "Sender's display name",
+ "lang_shareDeleteConfirm": "Do you really want to delete this network share?",
"lang_size": "Size",
"lang_spaceWastedDuplication": "Potentially wasted space by duplicate blocks",
+ "lang_specificUser": "Specific User",
"lang_ssl": "SSL mode",
"lang_sslExplicit": "Explicit SSL (\"STARTTLS\")",
"lang_sslImplicit": "Implicit SSL",
"lang_sslNone": "No SSL",
- "lang_subHeading": "Expired or damaged images",
"lang_superUser": "Is super user (can edit\/delete all lectures and VMs)",
"lang_system": "System",
+ "lang_target": "Target",
"lang_template": "Template",
"lang_templatePageDescription": "Here you can edit text fragments that are used to compose the information and reminder mails sent by the bwLehrpool server, e.g. when a lecture or VM is about to expire.",
"lang_test": "Send test mail",
@@ -83,10 +126,9 @@
"lang_updateTime": "Last update",
"lang_user": "User name",
"lang_userId": "User id",
- "lang_userList": "User List",
"lang_userListDescription": "Here you can promote \"super users\", which will have all permissions in the bwLehrpool-Suite. You can also ban users from accessing this server via the bwLehrpool-Suite.",
"lang_userListHeader": "Users known to this satellite",
"lang_usernameplaceholder": "SMTP Username",
"lang_version": "Version timestamp",
"lang_when": "When"
-}
+} \ No newline at end of file
diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php
index b58d57aa..67b791d1 100644
--- a/modules-available/dozmod/page.inc.php
+++ b/modules-available/dozmod/page.inc.php
@@ -2,25 +2,37 @@
class Page_DozMod extends Page
{
- /** @var \Page sub page classes */
- private $subPage = false;
+ /** @var bool true if we have a proper subpage */
+ private $haveSubPage = false;
+
+ private $validSections = ['expiredimages', 'mailconfig', 'templates', 'runtimeconfig', 'users', 'actionlog', 'networkshares', 'ldapfilters', 'runscripts', 'networkrules'];
+
+ private $section;
private function setupSubPage()
{
- if ($this->subPage !== false)
+ if ($this->haveSubPage !== false)
return;
/* different pages for different sections */
- $section = Request::any('section', 'mailconfig', 'string');
- /* instantiate sub pages */
- if ($section === 'templates') {
- $this->subPage = new Page_mail_templates();
- }
- if ($section === 'users') {
- $this->subPage = new Page_dozmod_users();
- }
- if ($section === 'actionlog') {
- $this->subPage = new Page_dozmod_log();
- }
+ $this->section = Request::any('section', false, 'string');
+ if ($this->section === 'blockstats') // HACK HACK
+ return;
+ if ($this->section === false) {
+ foreach ($this->validSections as $this->section) {
+ if (User::hasPermission($this->section . '.*'))
+ break;
+ }
+ } elseif (!in_array($this->section, $this->validSections)) {
+ Util::traceError('Invalid section: ' . $this->section);
+ }
+ // Check permissions
+ User::assertPermission($this->section . '.*');
+ $include = 'modules/' . Page::getModule()->getIdentifier() . '/pages/' . $this->section . '.inc.php';
+ if (!file_exists($include))
+ return;
+
+ require_once $include;
+ $this->haveSubPage = true;
}
protected function doPreprocess()
@@ -32,117 +44,45 @@ class Page_DozMod extends Page
Util::redirect('?do=Main');
}
- /* add sub-menus */
- Dashboard::addSubmenu('?do=dozmod&section=expiredimages', Dictionary::translate('submenu_expiredimages', true));
- Dashboard::addSubmenu('?do=dozmod&section=mailconfig', Dictionary::translate('submenu_mailconfig', true));
- Dashboard::addSubmenu('?do=dozmod&section=templates', Dictionary::translate('submenu_templates', true));
- Dashboard::addSubmenu('?do=dozmod&section=runtimeconfig', Dictionary::translate('submenu_runtime', true));
- Dashboard::addSubmenu('?do=dozmod&section=users', Dictionary::translate('submenu_users', true));
- Dashboard::addSubmenu('?do=dozmod&section=actionlog', Dictionary::translate('submenu_actionlog', true));
-
$this->setupSubPage();
- if ($this->subPage !== false) {
- $this->subPage->doPreprocess();
- return;
- }
-
- /* execute actions */
- $action = Request::post('action', false, 'string');
+ if ($this->haveSubPage !== false) {
+ SubPage::doPreprocess();
+ }
+ // Catch unhandled POST redirect
+ if (Request::isPost()) {
+ Util::redirect('?do=dozmod&section=' . $this->section);
+ }
+
+ /* Leave this here for translation module
+ Dictionary::translate('submenu_expiredimages', true);
+ Dictionary::translate('submenu_mailconfig', true);
+ Dictionary::translate('submenu_templates', true);
+ Dictionary::translate('submenu_runtimeconfig', true);
+ Dictionary::translate('submenu_users', true);
+ Dictionary::translate('submenu_actionlog', true);
+ Dictionary::translate('submenu_networkshares', true);
+ Dictionary::translate('submenu_ldapfilters', true);
+ Dictionary::translate('submenu_runscripts', true);
+ Dictionary::translate('submenu_networkrules', true);
+ */
- if ($action === 'mail') {
- if (User::hasPermission("mail.save")) {
- $this->mailHandler();
- }
- } elseif ($action === 'runtime') {
- if (User::hasPermission("runtimeconfig.save")) {
- $this->runtimeHandler();
- }
- } elseif ($action === 'delimages') {
- if (User::hasPermission("images.delete")) {
- $result = $this->handleDeleteImages();
- if (!empty($result)) {
- Message::addInfo('delete-images', $result);
- }
- Util::redirect('?do=DozMod');
+ /* add sub-menus */
+ foreach ($this->validSections as $section) {
+ if (User::hasPermission($section . '.*')) {
+ Dashboard::addSubmenu('?do=dozmod&section=' . $section, Dictionary::translate('submenu_' . $section, true));
}
- } elseif ($action !== false) {
- Util::traceError('Invalid action: ' . $action);
}
}
protected function doRender()
{
/* different pages for different sections */
- if ($this->subPage !== false) {
- $this->subPage->doRender();
+ if ($this->haveSubPage !== false) {
+ SubPage::doRender();
return;
}
- $section = Request::get('section', false, 'string');
-
- if ($section === false || $section === 'expiredimages') {
- $expiredImages = $this->loadExpiredImages();
- if ($section === false && empty($expiredImages)) {
- $section = 'mailconfig';
- } else {
- $section = 'expiredimages';
- }
- }
-
- if ($section === 'expiredimages') {
- if (empty($expiredImages)) {
- Message::addSuccess('no-expired-images');
- } else {
- Render::addTemplate('images-delete', array('images' => $expiredImages, 'allowedDelete' => User::hasPermission("images.delete")));
- }
- }
- if ($section === 'mailconfig') {
- // Mail config
- $mailConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig'));
- if ($mailConf != null) {
- $mailConf = @json_decode($mailConf['value'], true);
- if (is_array($mailConf)) {
- $mailConf['set_' . $mailConf['ssl']] = 'selected="selected"';
- }
- }
- $mailConf['allowedSave'] = User::hasPermission('mail.save');
- $mailConf['allowedTest'] = User::hasPermission('mail.testmail');
- Render::addTemplate('mailconfig', $mailConf);
- }
- if ($section === 'runtimeconfig') {
- // Runtime config
- $runtimeConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'runtimelimits'));
- if ($runtimeConf !== false) {
- $runtimeConf = json_decode($runtimeConf['value'], true);
-
- /* convert some value to corresponding "selected" texts */
- if ($runtimeConf['defaultLecturePermissions']['edit']) {
- $runtimeConf['defaultLecturePermissions']['edit'] = 'checked';
- }
- if ($runtimeConf['defaultLecturePermissions']['admin']) {
- $runtimeConf['defaultLecturePermissions']['admin'] = 'checked';
- }
- if ($runtimeConf['defaultImagePermissions']['edit']) {
- $runtimeConf['defaultImagePermissions']['edit'] = 'checked';
- }
- if ($runtimeConf['defaultImagePermissions']['admin']) {
- $runtimeConf['defaultImagePermissions']['admin'] = 'checked';
- }
- if ($runtimeConf['defaultImagePermissions']['link']) {
- $runtimeConf['defaultImagePermissions']['link'] = 'checked';
- }
- if ($runtimeConf['defaultImagePermissions']['download']) {
- $runtimeConf['defaultImagePermissions']['download'] = 'checked';
- }
-
- if ($runtimeConf['allowLoginByDefault']) {
- $runtimeConf['allowLoginByDefault'] = 'checked';
- }
- }
- $runtimeConf['allowedSave'] = User::hasPermission("runtimeconfig.save");
- Render::addTemplate('runtimeconfig', $runtimeConf);
- }
- if ($section === 'blockstats') {
+ if ($this->section === 'blockstats') {
$this->showBlockStats();
}
@@ -164,73 +104,19 @@ class Page_DozMod extends Page
Render::addTemplate('blockstats', $data);
}
- private function loadExpiredImages()
- {
- $res = Database::simpleQuery("SELECT b.displayname,"
- . " own.firstname, own.lastname, own.email,"
- . " v.imageversionid, v.createtime, v.filesize, v.deletestate,"
- . " lat.expiretime AS latexptime, lat.deletestate AS latdelstate"
- . " FROM sat.imageversion v"
- . " INNER JOIN sat.imagebase b ON (b.imagebaseid = v.imagebaseid)"
- . " INNER JOIN sat.user own ON (b.ownerid = own.userid)"
- . " LEFT JOIN sat.imageversion lat ON (b.latestversionid = lat.imageversionid)"
- . " WHERE v.deletestate <> 'KEEP'"
- . " ORDER BY b.displayname ASC, v.createtime ASC");
- $NOW = time();
- $rows = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if ($row['latexptime'] > $NOW && $row['latdelstate'] === 'KEEP') {
- $row['hasNewerClass'] = 'glyphicon-ok green';
- $row['checked'] = 'checked';
- } else {
- $row['hasNewerClass'] = 'glyphicon-remove red';
- }
- if ($row['deletestate'] === 'WANT_DELETE') {
- $row['name_extra_class'] = 'slx-strike';
- }
- $row['version'] = date('d.m.Y H:i:s', $row['createtime']);
- $row['rawfilesize'] = $row['filesize'];
- $row['filesize'] = Util::readableFileSize($row['filesize']);
- $rows[] = $row;
- }
- return $rows;
- }
-
- private function cleanMailArray()
- {
- $keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName');
- $data = array();
- foreach ($keys as $key) {
- $data[$key] = Request::post($key, '');
- settype($data[$key], 'string');
- if (is_numeric($data[$key])) {
- settype($data[$key], 'int');
- }
- }
- return $data;
- }
-
protected function doAjax()
{
User::load();
-
$this->setupSubPage();
- if ($this->subPage !== false) {
- $this->subPage->doAjax();
+
+ if ($this->haveSubPage !== false) {
+ SubPage::doAjax();
return;
}
$action = Request::post('action');
- if ($action === 'mail') {
- if (User::hasPermission("mail.testmail")) {
- $this->handleTestMail();
- }
- } elseif ($action === 'delimages') {
- if (User::hasPermission("images.delete")) {
- die($this->handleDeleteImages());
- }
- } elseif ($action === 'getblockinfo') {
+ if ($action === 'getblockinfo') {
$this->ajaxGetBlockInfo();
}
}
@@ -264,125 +150,4 @@ class Page_DozMod extends Page
die(Render::parse('blockstats-details', $data));
}
- private function handleDeleteImages()
- {
- $images = Request::post('images', false);
- if (is_array($images)) {
- foreach ($images as $image => $val) {
- if (strtolower($val) !== 'on')
- continue;
- Database::exec("UPDATE sat.imageversion SET deletestate = 'WANT_DELETE'"
- . " WHERE deletestate = 'SHOULD_DELETE' AND imageversionid = :imageversionid", array(
- 'imageversionid' => $image
- ));
- }
- if (!empty($images)) {
- $ret = Download::asStringPost('http://127.0.0.1:9080/do/delete-images', false, 10, $code);
- if ($code == 999) {
- $ret .= "\nConnection to DMSD failed.";
- }
- return $ret;
- }
- }
- return false;
- }
-
- private function handleTestMail()
- {
- $do = Request::post('button');
- if ($do === 'test') {
- // Prepare array
- $data = $this->cleanMailArray();
- Header('Content-Type: text/plain; charset=utf-8');
- $data['recipient'] = Request::post('recipient', '');
- if (!preg_match('/.+@.+\..+/', $data['recipient'])) {
- $result = 'No recipient given!';
- } else {
- $result = Download::asStringPost('http://127.0.0.1:9080/do/mailtest', $data, 10, $code);
- if ($code == 999) {
- $result .= "\nTimeout.";
- } elseif ($code != 200) {
- $result .= "\nReturn code $code";
- }
- }
- die($result);
- }
- }
-
- private function mailHandler()
- {
- // Check action
- $do = Request::post('button');
- if ($do === 'save') {
- // Prepare array
- $data = $this->cleanMailArray();
- $data = json_encode($data);
- Database::exec('INSERT INTO sat.configuration (parameter, value)'
- . ' VALUES (:param, :value)'
- . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array(
- 'param' => 'mailconfig',
- 'value' => $data
- ));
- Message::addSuccess('mail-config-saved');
- } else {
- Message::addError('main.invalid-action', $do);
- }
- Util::redirect('?do=DozMod&section=mailconfig');
- }
-
- private function runtimeHandler()
- {
- // Check action
- $do = Request::post('button');
- if ($do === 'save') {
- $data = [];
- $data['defaultLecturePermissions'] = Request::post('defaultLecturePermissions', NULL, "array");
- $data['defaultImagePermissions'] = Request::post('defaultImagePermissions', NULL, "array");
-
- $params = [
- 'int' => [
- 'maxImageValidityDays' => array('min' => 7, 'max' => 9999),
- 'maxLectureValidityDays' => array('min' => 7, 'max' => 9999),
- 'maxLocationsPerLecture' => array('min' => 0, 'max' => 999),
- 'maxTransfers' => array('min' => 1, 'max' => 10),
- ],
- 'bool' => [
- 'allowLoginByDefault' => array('default' => true)
- ],
- ];
- foreach ($params as $type => $list) {
- foreach ($list as $field => $limits) {
- $default = isset($limits['default']) ? $limits['default'] : false;
- $value = Request::post($field, $default);
- settype($value, $type);
- if (isset($limits['min']) && $value < $limits['min']) {
- $value = $limits['min'];
- }
- if (isset($limits['max']) && $value > $limits['max']) {
- $value = $limits['max'];
- }
- $data[$field] = $value;
- }
- }
-
- /* ensure types */
- settype($data['defaultLecturePermissions']['edit'], 'boolean');
- settype($data['defaultLecturePermissions']['admin'], 'boolean');
- settype($data['defaultImagePermissions']['edit'], 'boolean');
- settype($data['defaultImagePermissions']['admin'], 'boolean');
- settype($data['defaultImagePermissions']['link'], 'boolean');
- settype($data['defaultImagePermissions']['download'], 'boolean');
-
- $data = json_encode($data);
- Database::exec('INSERT INTO sat.configuration (parameter, value)'
- . ' VALUES (:param, :value)'
- . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array(
- 'param' => 'runtimelimits',
- 'value' => $data
- ));
- Message::addSuccess('runtimelimits-config-saved');
- }
- Util::redirect('?do=DozMod&section=runtimeconfig');
- }
-
}
diff --git a/modules-available/dozmod/inc/pagedozmodlog.inc.php b/modules-available/dozmod/pages/actionlog.inc.php
index 80441cd1..a014ddf7 100644
--- a/modules-available/dozmod/inc/pagedozmodlog.inc.php
+++ b/modules-available/dozmod/pages/actionlog.inc.php
@@ -1,25 +1,26 @@
<?php
-class Page_dozmod_log extends Page
+class SubPage
{
- private $action;
- private $uuid;
+ private static $action;
+ private static $uuid;
- protected function doPreprocess()
+ public static function doPreprocess()
{
- $this->action = Request::get('action', '', 'string');
- if ($this->action !== '' && $this->action !== 'showtarget' && $this->action !== 'showuser') {
- Util::traceError('Invalid action for actionlog: "' . $this->action . '"');
+ User::assertPermission("actionlog.view");
+ self::$action = Request::get('action', '', 'string');
+ if (self::$action !== '' && self::$action !== 'showtarget' && self::$action !== 'showuser') {
+ Util::traceError('Invalid action for actionlog: "' . self::$action . '"');
}
- $this->uuid = Request::get('uuid', '', 'string');
+ self::$uuid = Request::get('uuid', '', 'string');
}
- protected function doRender()
+ public static function doRender()
{
Render::addTemplate('actionlog-header');
- if ($this->action === '') {
- $this->generateLog("SELECT al.dateline, al.targetid, al.description,"
+ if (self::$action === '') {
+ self::generateLog("SELECT al.dateline, al.targetid, al.description,"
. " img.displayname AS imgname, tu.firstname AS tfirstname, tu.lastname AS tlastname, l.displayname AS lecturename,"
. " al.userid AS uuserid, usr.firstname AS ufirstname, usr.lastname AS ulastname"
. " FROM sat.actionlog al"
@@ -28,62 +29,58 @@ class Page_dozmod_log extends Page
. " LEFT JOIN sat.user tu ON (tu.userid = al.targetid)"
. " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)"
. " ORDER BY al.dateline DESC LIMIT 500", array(), true, true);
- } elseif ($this->action === 'showuser') {
- if (User::hasPermission("log.showuser")) {
- $this->listUser();
- }
+ } elseif (self::$action === 'showuser') {
+ self::listUser();
} else {
- if (User::hasPermission("log.showtarget")) {
- $this->listTarget();
- }
+ self::listTarget();
}
}
- private function listUser()
+ private static function listUser()
{
// Query user
$user = Database::queryFirst('SELECT userid, firstname, lastname, email, lastlogin,'
. ' organization.displayname AS orgname FROM sat.user'
. ' LEFT JOIN sat.organization USING (organizationid)'
. ' WHERE userid = :uuid'
- . ' LIMIT 1', array('uuid' => $this->uuid));
+ . ' LIMIT 1', array('uuid' => self::$uuid));
if ($user === false) {
- Message::addError('unknown-userid', $this->uuid);
+ Message::addError('unknown-userid', self::$uuid);
Util::redirect('?do=dozmod&section=actionlog');
}
// Mangle date and render
$user['lastlogin_s'] = date('d.m.Y H:i', $user['lastlogin']);
Render::addTemplate('actionlog-user', $user);
// Finally add the actionlog
- $this->generateLog("SELECT al.dateline, al.targetid, al.description,"
+ self::generateLog("SELECT al.dateline, al.targetid, al.description,"
. " img.displayname AS imgname, usr.firstname AS tfirstname, usr.lastname AS tlastname, l.displayname AS lecturename"
. " FROM sat.actionlog al"
. " LEFT JOIN sat.imagebase img ON (img.imagebaseid = targetid)"
. " LEFT JOIN sat.user usr ON (usr.userid = targetid)"
. " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)"
. " WHERE al.userid = :uuid"
- . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => $this->uuid), false, true);
+ . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => self::$uuid), false, true);
}
- private function listTarget()
+ private static function listTarget()
{
// We have to guess what kind of target it is
- if (!$this->addImageHeader()
- && !$this->addLectureHeader()) {
- Message::addError('unknown-targetid', $this->uuid);
+ if (!self::addImageHeader()
+ && !self::addLectureHeader()) {
+ Message::addError('unknown-targetid', self::$uuid);
// Keep going, there might still be log entries for a deleted uuid
}
// Finally add the actionlog
- $this->generateLog("SELECT al.dateline, al.userid AS uuserid, al.description,"
+ self::generateLog("SELECT al.dateline, al.userid AS uuserid, al.description,"
. " usr.firstname AS ufirstname, usr.lastname AS ulastname"
. " FROM sat.actionlog al"
. " LEFT JOIN sat.user usr ON (usr.userid = al.userid)"
. " WHERE al.targetid = :uuid"
- . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => $this->uuid), true, false);
+ . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => self::$uuid), true, false);
}
- private function addImageHeader()
+ private static function addImageHeader()
{
$image = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname,'
. ' u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname,'
@@ -94,7 +91,7 @@ class Page_dozmod_log extends Page
. ' LEFT JOIN sat.user u ON (img.updaterid = u.userid)'
. ' LEFT JOIN sat.operatingsystem os ON (img.osid = os.osid)'
. ' WHERE img.imagebaseid = :uuid'
- . ' LIMIT 1', array('uuid' => $this->uuid));
+ . ' LIMIT 1', array('uuid' => self::$uuid));
if ($image !== false) {
// Mangle date and render
$image['createtime_s'] = date('d.m.Y H:i', $image['createtime']);
@@ -105,7 +102,7 @@ class Page_dozmod_log extends Page
return $image !== false;
}
- private function addLectureHeader()
+ private static function addLectureHeader()
{
$lecture = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname,'
. ' u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname,'
@@ -117,7 +114,7 @@ class Page_dozmod_log extends Page
. ' LEFT JOIN sat.imageversion ver ON (ver.imageversionid = l.imageversionid)'
. ' LEFT JOIN sat.imagebase img ON (img.imagebaseid = ver.imagebaseid)'
. ' WHERE l.lectureid = :uuid'
- . ' LIMIT 1', array('uuid' => $this->uuid));
+ . ' LIMIT 1', array('uuid' => self::$uuid));
if ($lecture !== false) {
// Mangle date and render
$lecture['createtime_s'] = date('d.m.Y H:i', $lecture['createtime']);
@@ -128,7 +125,7 @@ class Page_dozmod_log extends Page
return $lecture !== false;
}
- private function generateLog($query, $params, $showActor, $showTarget)
+ private static function generateLog($query, $params, $showActor, $showTarget)
{
// query action log
$res = Database::simpleQuery($query, $params);
@@ -155,9 +152,12 @@ class Page_dozmod_log extends Page
$data['showTarget'] = true;
}
- $data['allowedShowUser'] = User::hasPermission("log.showuser");
- $data['allowedShowTarget'] = User::hasPermission("log.showtarget");
Render::addTemplate('actionlog-log', $data);
}
+ public static function doAjax()
+ {
+
+ }
+
} \ No newline at end of file
diff --git a/modules-available/dozmod/pages/expiredimages.inc.php b/modules-available/dozmod/pages/expiredimages.inc.php
new file mode 100644
index 00000000..2b5a2274
--- /dev/null
+++ b/modules-available/dozmod/pages/expiredimages.inc.php
@@ -0,0 +1,97 @@
+<?php
+
+class SubPage
+{
+
+ public static function doPreprocess()
+ {
+ $action = Request::post('action', false, 'string');
+
+ if ($action === 'delimages') {
+ if (User::hasPermission("expiredimages.delete")) {
+ $result = self::handleDeleteImages();
+ if (!empty($result)) {
+ Message::addInfo('delete-images', $result);
+ }
+ Util::redirect('?do=DozMod');
+ }
+ }
+ }
+
+ private static function handleDeleteImages()
+ {
+ $images = Request::post('images', false);
+ if (is_array($images)) {
+ foreach ($images as $image => $val) {
+ if (strtolower($val) !== 'on')
+ continue;
+ Database::exec("UPDATE sat.imageversion SET deletestate = 'WANT_DELETE'"
+ . " WHERE deletestate = 'SHOULD_DELETE' AND imageversionid = :imageversionid", array(
+ 'imageversionid' => $image
+ ));
+ }
+ if (!empty($images)) {
+ $ret = Download::asStringPost('http://127.0.0.1:9080/do/delete-images', false, 10, $code);
+ if ($code == 999) {
+ $ret .= "\nConnection to DMSD failed.";
+ }
+ return $ret;
+ }
+ }
+ return false;
+ }
+
+ private static function loadExpiredImages()
+ {
+ $res = Database::simpleQuery("SELECT b.displayname,"
+ . " own.firstname, own.lastname, own.email,"
+ . " v.imageversionid, v.createtime, v.filesize, v.deletestate,"
+ . " lat.expiretime AS latexptime, lat.deletestate AS latdelstate"
+ . " FROM sat.imageversion v"
+ . " INNER JOIN sat.imagebase b ON (b.imagebaseid = v.imagebaseid)"
+ . " INNER JOIN sat.user own ON (b.ownerid = own.userid)"
+ . " LEFT JOIN sat.imageversion lat ON (b.latestversionid = lat.imageversionid)"
+ . " WHERE v.deletestate <> 'KEEP'"
+ . " ORDER BY b.displayname ASC, v.createtime ASC");
+ $NOW = time();
+ $rows = array();
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['latexptime'] > $NOW && $row['latdelstate'] === 'KEEP') {
+ $row['hasNewerClass'] = 'glyphicon-ok green';
+ $row['checked'] = 'checked';
+ } else {
+ $row['hasNewerClass'] = 'glyphicon-remove red';
+ }
+ if ($row['deletestate'] === 'WANT_DELETE') {
+ $row['name_extra_class'] = 'slx-strike';
+ }
+ $row['version'] = date('d.m.Y H:i:s', $row['createtime']);
+ $row['rawfilesize'] = $row['filesize'];
+ $row['filesize'] = Util::readableFileSize($row['filesize']);
+ $rows[] = $row;
+ }
+ return $rows;
+ }
+
+ public static function doRender()
+ {
+ $expiredImages = self::loadExpiredImages();
+
+ if (empty($expiredImages)) {
+ Message::addSuccess('no-expired-images');
+ } else {
+ Render::addTemplate('images-delete', array('images' => $expiredImages, 'allowedDelete' => User::hasPermission("expiredimages.delete")));
+ }
+ }
+
+ public static function doAjax()
+ {
+ $action = Request::post('action');
+ if ($action === 'delimages') {
+ User::assertPermission("expiredimages.delete");
+ die(self::handleDeleteImages());
+ }
+ die('Huh?');
+ }
+
+}
diff --git a/modules-available/dozmod/pages/ldapfilters.inc.php b/modules-available/dozmod/pages/ldapfilters.inc.php
new file mode 100644
index 00000000..d0ae41b8
--- /dev/null
+++ b/modules-available/dozmod/pages/ldapfilters.inc.php
@@ -0,0 +1,119 @@
+<?php
+
+class SubPage
+{
+ private static $show;
+
+ public static function doPreprocess()
+ {
+ self::$show = Request::any('show', false, 'string');
+ $action = Request::post('action');
+
+ if ($action === 'deleteFilter') {
+ User::assertPermission("ldapfilters.save");
+ self::deleteLdapFilter();
+ } else if ($action === 'saveFilter') {
+ User::assertPermission("ldapfilters.save");
+ self::saveLdapFilter();
+ }
+ User::assertPermission("ldapfilters.view");
+ }
+
+ public static function doRender()
+ {
+ if (self::$show === false) {
+ // Get all ldapfilters from the sat db.
+ $ldapfilters = Database::queryAll("SELECT filterid, filtername, filterkey, filtervalue FROM sat.presetlecturefilter
+ WHERE filtertype ='LDAP' ORDER BY filtername ASC");
+
+ $data = array(
+ 'ldapfilters' => $ldapfilters,
+ 'hasEditPermission' => User::hasPermission('ldapfilters.save')
+ );
+
+ Render::addTemplate('ldapfilters', $data);
+ } else if (self::$show === 'edit') {
+ $filterid = Request::get('filterid', false, 'int');
+
+ if ($filterid === false) {
+ Render::addTemplate('ldapfilter-add', array(
+ 'filterid' => 0
+ ));
+ } else {
+ $ldapfilter = Database::queryFirst("SELECT filterid, filtername, filterkey, filtervalue FROM sat.presetlecturefilter
+ WHERE filterid = :id AND filtertype = 'LDAP'", array( 'id' => $filterid));
+ // TODO: Show error if not exists
+
+ Render::addTemplate('ldapfilter-add', $ldapfilter);
+ }
+ }
+ }
+
+ private static function deleteLdapFilter() {
+ User::assertPermission('ldapfilters.save');
+ $filterid = Request::post('filterid', false, 'int');
+ if ($filterid === false) {
+ Message::addError('ldap-filter-id-missing');
+ return;
+ }
+ $res = Database::exec("DELETE FROM sat.presetlecturefilter WHERE filterid = :id AND filtertype = 'LDAP'", array('id' => $filterid));
+ if ($res !== 1) {
+ Message::addWarning('ldap-invalid-filter-id', $filterid);
+ } else {
+ Message::addSuccess('ldap-filter-deleted');
+ }
+ }
+
+ private static function saveLdapFilter() {
+ $filterid = Request::post('filterid', '', 'int');
+ $filtername = Request::post('filtername', false, 'string');
+ $filterattribute = Request::post('attribute', false, 'string');
+ $filtervalue = Request::post('value', false, 'string');
+
+ if ($filtername === false || $filterattribute === false || $filtervalue === false) {
+ Message::addError('ldap-filter-save-missing-information');
+ return;
+ }
+
+ if ($filterid === 0) {
+ // Insert filter in the db.
+ $res = Database::exec("INSERT INTO sat.presetlecturefilter (filtertype, filtername, filterkey, filtervalue)
+ VALUES ('LDAP', :filtername, :attribute, :value)", array(
+ 'filtername' => $filtername,
+ 'attribute' => $filterattribute,
+ 'value' => $filtervalue
+ ));
+
+ if ($res !== 1) {
+ Message::addError('ldap-filter-insert-failed');
+ } else {
+ Message::addSuccess('ldap-filter-created');
+ }
+
+ } else {
+ // Update filter in the db.
+ $res = Database::exec("UPDATE sat.presetlecturefilter SET
+ filtername = :filtername, filterkey = :attribute, filtervalue = :value
+ WHERE filterid = :filterid AND filtertype = 'LDAP'", array(
+ 'filterid' => $filterid,
+ 'filtername' => $filtername,
+ 'attribute' => $filterattribute,
+ 'value' => $filtervalue
+ ));
+
+ if ($res !== 1) {
+ Message::addError('ldap-filter-insert-failed');
+ } else {
+ Message::addSuccess('ldap-filter-saved');
+ }
+
+ }
+ Util::redirect("?do=dozmod&section=ldapfilters");
+ }
+
+ public static function doAjax()
+ {
+
+ }
+
+} \ No newline at end of file
diff --git a/modules-available/dozmod/pages/mailconfig.inc.php b/modules-available/dozmod/pages/mailconfig.inc.php
new file mode 100644
index 00000000..08205f2e
--- /dev/null
+++ b/modules-available/dozmod/pages/mailconfig.inc.php
@@ -0,0 +1,96 @@
+<?php
+
+class SubPage
+{
+
+ public static function doPreprocess()
+ {
+ $action = Request::post('action', false, 'string');
+
+ if ($action === 'mail') {
+ User::assertPermission("mailconfig.save");
+ self::mailHandler();
+ }
+ }
+
+ private static function mailHandler()
+ {
+ // Check action
+ $do = Request::post('button');
+ if ($do === 'save') {
+ // Prepare array
+ $data = self::cleanMailArray();
+ $data = json_encode($data);
+ Database::exec('INSERT INTO sat.configuration (parameter, value)'
+ . ' VALUES (:param, :value)'
+ . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array(
+ 'param' => 'mailconfig',
+ 'value' => $data
+ ));
+ Message::addSuccess('mail-config-saved');
+ } else {
+ Message::addError('main.invalid-action', $do);
+ }
+ Util::redirect('?do=DozMod&section=mailconfig');
+ }
+
+ private static function cleanMailArray()
+ {
+ $keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName');
+ $data = array();
+ foreach ($keys as $key) {
+ $data[$key] = Request::post($key, '');
+ settype($data[$key], 'string');
+ if (is_numeric($data[$key])) {
+ settype($data[$key], 'int');
+ }
+ }
+ return $data;
+ }
+
+ public static function doRender()
+ {
+ // Mail config
+ $mailConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig'));
+ if ($mailConf != null) {
+ $mailConf = @json_decode($mailConf['value'], true);
+ if (is_array($mailConf)) {
+ $mailConf['set_' . $mailConf['ssl']] = 'selected="selected"';
+ }
+ }
+ Permission::addGlobalTags($mailConf['perms'], null, ['mailconfig.save']);
+ Render::addTemplate('mailconfig', $mailConf);
+ }
+
+ public static function doAjax()
+ {
+ User::assertPermission("mailconfig.save");
+ $action = Request::post('action');
+ if ($action === 'mail') {
+ self::handleTestMail();
+ }
+ }
+
+ private static function handleTestMail()
+ {
+ $do = Request::post('button');
+ if ($do === 'test') {
+ // Prepare array
+ $data = self::cleanMailArray();
+ Header('Content-Type: text/plain; charset=utf-8');
+ $data['recipient'] = Request::post('recipient', '');
+ if (!preg_match('/.+@.+\..+/', $data['recipient'])) {
+ $result = 'No recipient given!';
+ } else {
+ $result = Download::asStringPost('http://127.0.0.1:9080/do/mailtest', $data, 10, $code);
+ if ($code == 999) {
+ $result .= "\nTimeout.";
+ } elseif ($code != 200) {
+ $result .= "\nReturn code $code";
+ }
+ }
+ die($result);
+ }
+ }
+
+}
diff --git a/modules-available/dozmod/pages/networkrules.inc.php b/modules-available/dozmod/pages/networkrules.inc.php
new file mode 100644
index 00000000..6011e3ff
--- /dev/null
+++ b/modules-available/dozmod/pages/networkrules.inc.php
@@ -0,0 +1,98 @@
+<?php
+
+class SubPage
+{
+
+ public static function doPreprocess()
+ {
+ $action = Request::post('action', '', 'string');
+
+ if ($action === 'delete') {
+ User::assertPermission('networkrules.save');
+ $ruleid = Request::post('ruleid', false, 'int');
+ if ($ruleid !== false) {
+ $res = Database::exec('DELETE FROM sat.presetnetworkrules WHERE ruleid = :ruleid', ['ruleid' => $ruleid]);
+ if ($res !== false) {
+ Message::addSuccess('networkrule-deleted');
+ }
+ }
+ } else if ($action === 'save') {
+ User::assertPermission('networkrules.save');
+ $ruleid = Request::post('ruleid', 0, 'int');
+ $rulename = Request::post('rulename', '', 'string');
+ $host = Request::post('host', '', 'string');
+ $port = Request::post('port', '', 'string');
+ $direction = Request::post('direction', '', 'string');
+
+ if (!in_array($direction, ['IN', 'OUT'], true)) {
+ Message::addError('networkrule-invalid-direction', $direction);
+ } elseif (empty($host)) {
+ Message::addError('networkrule-missing-host');
+ } elseif (empty($port)) {
+ Message::addError('networkrule-missing-port');
+ } else {
+ $data = json_encode([
+ 'host' => $host,
+ 'port' => $port,
+ 'direction' => $direction
+ ]);
+ if ($ruleid !== 0) {
+ Database::exec('UPDATE sat.presetnetworkrules SET rulename = :rulename, ruledata = :data'
+ .' WHERE ruleid = :ruleid', compact('ruleid', 'rulename', 'data'));
+ } else {
+ Database::exec('INSERT INTO sat.presetnetworkrules (rulename, ruledata)'
+ .' VALUES (:rulename, :data)', compact('rulename', 'data'));
+ }
+ Message::addSuccess('networkrule-saved');
+ }
+ }
+ if (Request::isPost()) {
+ Util::redirect('?do=dozmod&section=networkrules');
+ }
+ User::assertPermission('networkrules.view');
+ }
+
+ public static function doRender()
+ {
+ $show = Request::get('show', 'list', 'string');
+ if ($show === 'list') {
+ $res = Database::simpleQuery('SELECT ruleid, rulename, ruledata
+ FROM sat.presetnetworkrules ORDER BY rulename ASC');
+ $rows = array();
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $dec = json_decode($row['ruledata'], true);
+ if (!is_array($dec)) {
+ $dec = [];
+ }
+ $rows[] = $row + $dec;
+ }
+ Render::addTemplate('networkrules', [
+ 'networkrules' => $rows,
+ 'hasEditPermissions' => User::hasPermission('networkrules.save')
+ ]);
+ } else if ($show === 'edit') {
+ $ruleid = Request::get('ruleid', 0, 'int');
+ if ($ruleid === 0) {
+ $data = [];
+ } else {
+ $data = Database::queryFirst('SELECT ruleid, rulename, ruledata
+ FROM sat.presetnetworkrules WHERE ruleid = :ruleid', ['ruleid' => $ruleid]);
+ if ($data === false) {
+ Message::addError('networkrule-invalid-ruleid', $ruleid);
+ Util::redirect('?do=dozmod&section=networkrules');
+ }
+ $dec = json_decode($data['ruledata'], true);
+ if (is_array($dec)) {
+ $data += $dec;
+ }
+ if ($data['direction'] === 'IN') {
+ $data['inSelected'] = 'selected';
+ } else {
+ $data['outSelected'] = 'selected';
+ }
+ }
+ Render::addTemplate('networkrules-edit', $data);
+ }
+ }
+
+}
diff --git a/modules-available/dozmod/pages/networkshares.inc.php b/modules-available/dozmod/pages/networkshares.inc.php
new file mode 100644
index 00000000..659321b4
--- /dev/null
+++ b/modules-available/dozmod/pages/networkshares.inc.php
@@ -0,0 +1,108 @@
+<?php
+
+class SubPage
+{
+
+ public static function doPreprocess()
+ {
+ $action = Request::post('action', '', 'string');
+
+ if ($action === 'delete') {
+ User::assertPermission('networkshares.save');
+ $shareid = Request::post('shareid', false, 'int');
+ if ($shareid !== false) {
+ $res = Database::exec('DELETE FROM sat.presetnetworkshare WHERE shareid = :shareid', ['shareid' => $shareid]);
+ if ($res !== false) {
+ Message::addSuccess('networkshare-deleted');
+ }
+ }
+ } else if ($action === 'save') {
+ User::assertPermission('networkshares.save');
+ $shareid = Request::post('shareid', 0, 'int');
+ $sharename = Request::post('sharename', '', 'string');
+ $path = Request::post('path', false, 'string');
+ $target = Request::post('target', '', 'string');
+ $authType = Request::post('auth', '', 'string');
+ $username = Request::post('username', '', 'string');
+ $password = Request::post('password', '', 'string');
+ if (!in_array($authType, ['LOGIN_USER', 'OTHER_USER'], true)) {
+ Message::addError('networkshare-invalid-auth-type', $authType);
+ } elseif (empty($path)) {
+ Message::addError('networkshare-missing-path');
+ } else {
+ $data = json_encode([
+ 'auth' => $authType,
+ 'path' => $path,
+ 'displayname' => $sharename,
+ 'mountpoint' => $target,
+ 'username' => $username,
+ 'password' => $password,
+ ]);
+ if ($shareid !== 0) {
+ Database::exec('UPDATE sat.presetnetworkshare SET sharename = :sharename, sharedata = :data'
+ .' WHERE shareid = :shareid', compact('shareid', 'sharename', 'data'));
+ } else {
+ Database::exec('INSERT INTO sat.presetnetworkshare (sharename, sharedata, active)'
+ .' VALUES (:sharename, :data, 1)', compact('sharename', 'data'));
+ }
+ Message::addSuccess('networkshare-saved');
+ }
+ } else if ($action === 'activate' || $action === 'deactivate') {
+ User::assertPermission('networkshares.save');
+ $shareid = Request::post('shareid', false, 'int');
+ $active = ($action === 'activate' ? 1 : 0);
+ Database::exec('UPDATE sat.presetnetworkshare SET active = :active WHERE shareid = :shareid', compact('active', 'shareid'));
+ }
+ if (Request::isPost()) {
+ Util::redirect('?do=dozmod&section=networkshares');
+ }
+ User::assertPermission('networkshares.view');
+ }
+
+ public static function doRender()
+ {
+ $show = Request::get('show', 'list', 'string');
+ if ($show === 'list') {
+ $res = Database::simpleQuery('SELECT shareid, sharename, sharedata, active
+ FROM sat.presetnetworkshare ORDER BY sharename ASC');
+ $rows = array();
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $dec = json_decode($row['sharedata'], true);
+ if (!is_array($dec)) {
+ $dec = [];
+ }
+ if ($dec['auth'] === 'LOGIN_USER') {
+ $row['loginAsUser'] = true;
+ }
+ $rows[] = $row + $dec;
+ }
+ Render::addTemplate('networkshares', [
+ 'networkshares' => $rows,
+ 'hasEditPermissions' => User::hasPermission('networkshares.save')
+ ]);
+ } else if ($show === 'edit') {
+ $shareid = Request::get('shareid', 0, 'int');
+ if ($shareid === 0) {
+ $data = [];
+ } else {
+ $data = Database::queryFirst('SELECT shareid, sharename, sharedata
+ FROM sat.presetnetworkshare WHERE shareid = :shareid', ['shareid' => $shareid]);
+ if ($data === false) {
+ Message::addError('networkshare-invalid-shareid', $shareid);
+ Util::redirect('?do=dozmod&section=networkshares');
+ }
+ $dec = json_decode($data['sharedata'], true);
+ if (is_array($dec)) {
+ $data += $dec;
+ }
+ if ($data['auth'] === 'LOGIN_USER') {
+ $data['loggedInUser_selected'] = 'selected';
+ } else {
+ $data['specificUser_selected'] = 'selected';
+ }
+ }
+ Render::addTemplate('networkshares-edit', $data);
+ }
+ }
+
+}
diff --git a/modules-available/dozmod/pages/runscripts.inc.php b/modules-available/dozmod/pages/runscripts.inc.php
new file mode 100644
index 00000000..c6566c13
--- /dev/null
+++ b/modules-available/dozmod/pages/runscripts.inc.php
@@ -0,0 +1,133 @@
+<?php
+
+class SubPage
+{
+
+ public static function doPreprocess()
+ {
+ /* execute actions */
+ $action = Request::post('action', false, 'string');
+
+ if ($action === 'save') {
+ User::assertPermission("runscripts.save");
+ self::saveScript();
+ }
+
+ if (Request::isPost()) {
+ Util::redirect('?do=dozmod&section=runscripts');
+ }
+ User::assertPermission('runscripts.view');
+ }
+
+ private static function saveScript()
+ {
+ $id = Request::post('runscriptid', false, 'int');
+ $scriptname = Request::post('scriptname', '', 'string');
+ if ($id === false) {
+ Message::addError('main.parameter-missing', 'runscriptid');
+ return;
+ }
+ $data = [
+ 'scriptname' => $scriptname,
+ 'content' => Request::post('content', '', 'string'),
+ 'visibility' => Request::post('visibility', 1, 'int'),
+ 'extension' => preg_replace('/[^a-z0-9_\-~\!\$\=]/i', '', Request::post('extension', '', 'string')),
+ 'passcreds' => Request::post('passcreds', 0, 'int') !== 0,
+ 'isglobal' => Request::post('isglobal', 0, 'int') !== 0,
+ ];
+ if ($id === 0) {
+ // New entry
+ $ret = Database::exec('INSERT INTO sat.presetrunscript
+ (scriptname, content, extension, visibility, passcreds, isglobal) VALUES
+ (:scriptname, :content, :extension, :visibility, :passcreds, :isglobal)', $data);
+ $id = Database::lastInsertId();
+ } else {
+ // Edit entry
+ $data['id'] = $id;
+ Database::exec('UPDATE sat.presetrunscript SET
+ scriptname = :scriptname, content = :content, extension = :extension, visibility = :visibility,
+ passcreds = :passcreds, isglobal = :isglobal
+ WHERE runscriptid = :id', $data);
+ }
+ $oslist = Request::post('osid', false, 'array');
+ if (is_array($oslist)) {
+ $oslist = array_filter($oslist, 'is_numeric');
+ $query = Database::prepare('INSERT INTO sat.presetrunscript_x_operatingsystem
+ (runscriptid, osid) VALUES (:id, :osid)');
+ foreach ($oslist as $osid) {
+ $query->execute(['id' => $id, 'osid' => $osid]);
+ }
+ $query->closeCursor();
+ Database::exec('DELETE FROM sat.presetrunscript_x_operatingsystem
+ WHERE runscriptid = :id AND osid NOT IN (:oslist)', ['id' => $id, 'oslist' => $oslist]);
+ }
+ Message::addSuccess('runscript-saved');
+ }
+
+ public static function doRender()
+ {
+ $show = Request::get('show', 'list', 'string');
+ if ($show === 'list') {
+ $res = Database::simpleQuery('SELECT runscriptid, scriptname, extension, visibility, passcreds, isglobal
+ FROM sat.presetrunscript
+ ORDER BY scriptname ASC');
+ $rows = [];
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['visibility'] == 0) {
+ $row['visibility'] = 'eye-close';
+ } elseif ($row['visibility'] == 1) {
+ $row['visibility'] = 'eye-open';
+ } else {
+ $row['visibility'] = 'arrow-down';
+ }
+ $rows[] = $row;
+ }
+ Render::addTemplate('runscripts-list', ['list' => $rows, 'hasEditPermission' => User::hasPermission('runscripts.save')]);
+ } elseif ($show === 'edit') {
+ // Edit
+ $id = Request::get('runscriptid', false, 'int');
+ if ($id === false) {
+ Message::addError('main.parameter-missing', 'runscriptid');
+ Util::redirect('?do=dozmod&section=runscripts');
+ }
+ if ($id === 0) {
+ $row = [
+ 'runscriptid' => 0,
+ 'visibility_1_checked' => 'checked',
+ 'isglobal_1_checked' => 'checked',
+ ];
+ } else {
+ $row = Database::queryFirst('SELECT runscriptid, scriptname, content, extension, visibility, passcreds, isglobal
+ FROM sat.presetrunscript
+ WHERE runscriptid = :runscriptid', ['runscriptid' => $id]);
+ $row['visibility_' . $row['visibility'] . '_selected'] = 'selected';
+ $row['passcreds_checked'] = $row['passcreds'] ? 'checked' : '';
+ $row['isglobal_' . $row['isglobal'] . '_checked'] = 'checked';
+ if ($row === false) {
+ Message::addError('runscript-invalid-id', $id);
+ Util::redirect('?do=dozmod&section=runscripts');
+ }
+ }
+ // Get OS
+ $row['oslist'] = [];
+ $res = Database::simpleQuery('SELECT o.osid, o.displayname, pxo.osid AS isvalid FROM sat.operatingsystem o
+ LEFT JOIN sat.presetrunscript_x_operatingsystem pxo ON (o.osid = pxo.osid AND pxo.runscriptid = :runscriptid)
+ ORDER BY o.displayname ASC', ['runscriptid' => $id]);
+ while ($osrow = $res->fetch(PDO::FETCH_ASSOC)) {
+ $row['oslist'][] = [
+ 'osid' => $osrow['osid'],
+ 'displayname' => $osrow['displayname'],
+ 'checked' => $osrow['isvalid'] ? 'checked' : '',
+ ];
+ }
+ // Output
+ Render::addTemplate('runscripts-edit', $row);
+ }
+ }
+
+ public static function doAjax()
+ {
+
+ }
+
+}
diff --git a/modules-available/dozmod/pages/runtimeconfig.inc.php b/modules-available/dozmod/pages/runtimeconfig.inc.php
new file mode 100644
index 00000000..63ba4650
--- /dev/null
+++ b/modules-available/dozmod/pages/runtimeconfig.inc.php
@@ -0,0 +1,112 @@
+<?php
+
+class SubPage
+{
+
+ public static function doPreprocess()
+ {
+ /* execute actions */
+ $action = Request::post('action', false, 'string');
+
+ if ($action === 'runtime') {
+ User::assertPermission("runtimeconfig.save");
+ self::runtimeHandler();
+ }
+ }
+
+ private static function runtimeHandler()
+ {
+ // Check action
+ $do = Request::post('button');
+ if ($do === 'save') {
+ $data = [];
+ $data['defaultLecturePermissions'] = Request::post('defaultLecturePermissions', NULL, "array");
+ $data['defaultImagePermissions'] = Request::post('defaultImagePermissions', NULL, "array");
+
+ $params = [
+ 'int' => [
+ 'maxImageValidityDays' => array('min' => 7, 'max' => 9999),
+ 'maxLectureValidityDays' => array('min' => 7, 'max' => 9999),
+ 'maxLocationsPerLecture' => array('min' => 0, 'max' => 999),
+ 'maxTransfers' => array('min' => 1, 'max' => 10),
+ ],
+ 'bool' => [
+ 'allowLoginByDefault' => array('default' => true)
+ ],
+ ];
+ foreach ($params as $type => $list) {
+ foreach ($list as $field => $limits) {
+ $default = isset($limits['default']) ? $limits['default'] : false;
+ $value = Request::post($field, $default);
+ settype($value, $type);
+ if (isset($limits['min']) && $value < $limits['min']) {
+ $value = $limits['min'];
+ }
+ if (isset($limits['max']) && $value > $limits['max']) {
+ $value = $limits['max'];
+ }
+ $data[$field] = $value;
+ }
+ }
+
+ /* ensure types */
+ settype($data['defaultLecturePermissions']['edit'], 'boolean');
+ settype($data['defaultLecturePermissions']['admin'], 'boolean');
+ settype($data['defaultImagePermissions']['edit'], 'boolean');
+ settype($data['defaultImagePermissions']['admin'], 'boolean');
+ settype($data['defaultImagePermissions']['link'], 'boolean');
+ settype($data['defaultImagePermissions']['download'], 'boolean');
+
+ $data = json_encode($data);
+ Database::exec('INSERT INTO sat.configuration (parameter, value)'
+ . ' VALUES (:param, :value)'
+ . ' ON DUPLICATE KEY UPDATE value = VALUES(value)', array(
+ 'param' => 'runtimelimits',
+ 'value' => $data
+ ));
+ Message::addSuccess('runtimelimits-config-saved');
+ }
+ Util::redirect('?do=DozMod&section=runtimeconfig');
+ }
+
+ public static function doRender()
+ {
+ // Runtime config
+ $runtimeConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'runtimelimits'));
+ if ($runtimeConf !== false) {
+ $runtimeConf = json_decode($runtimeConf['value'], true);
+
+ /* convert some value to corresponding "selected" texts */
+ if ($runtimeConf['defaultLecturePermissions']['edit']) {
+ $runtimeConf['defaultLecturePermissions']['edit'] = 'checked';
+ }
+ if ($runtimeConf['defaultLecturePermissions']['admin']) {
+ $runtimeConf['defaultLecturePermissions']['admin'] = 'checked';
+ }
+ if ($runtimeConf['defaultImagePermissions']['edit']) {
+ $runtimeConf['defaultImagePermissions']['edit'] = 'checked';
+ }
+ if ($runtimeConf['defaultImagePermissions']['admin']) {
+ $runtimeConf['defaultImagePermissions']['admin'] = 'checked';
+ }
+ if ($runtimeConf['defaultImagePermissions']['link']) {
+ $runtimeConf['defaultImagePermissions']['link'] = 'checked';
+ }
+ if ($runtimeConf['defaultImagePermissions']['download']) {
+ $runtimeConf['defaultImagePermissions']['download'] = 'checked';
+ }
+
+ if ($runtimeConf['allowLoginByDefault']) {
+ $runtimeConf['allowLoginByDefault'] = 'checked';
+ }
+ }
+ $runtimeConf['allowedSave'] = User::hasPermission("runtimeconfig.save");
+ Render::addTemplate('runtimeconfig', $runtimeConf);
+ }
+
+ public static function doAjax()
+ {
+
+ }
+
+}
diff --git a/modules-available/dozmod/inc/pagemailtemplates.inc.php b/modules-available/dozmod/pages/templates.inc.php
index ff47977f..b857115f 100644
--- a/modules-available/dozmod/inc/pagemailtemplates.inc.php
+++ b/modules-available/dozmod/pages/templates.inc.php
@@ -1,24 +1,22 @@
<?php
-class Page_mail_templates extends Page
+class SubPage
{
- private $templates = [];
+ private static $templates = [];
- protected function doPreprocess()
+ public static function doPreprocess()
{
- User::load();
-
$action = Request::post('action', 'show', 'string');
if ($action === 'show') {
- $this->fetchTemplates();
+ self::fetchTemplates();
} elseif ($action === 'save') {
if (User::hasPermission("templates.save")) {
- $this->handleSave();
+ self::handleSave();
}
} elseif ($action === 'reset') {
if(User::hasPermission("templates.reset")) {
- $this->handleReset();
+ self::handleReset();
}
} else {
Message::addError('main.invalid-action', $action);
@@ -26,9 +24,9 @@ class Page_mail_templates extends Page
}
}
- private function enrichHtml() {
+ private static function enrichHtml() {
/* for each template */
- foreach ($this->templates as &$t) {
+ foreach (self::$templates as &$t) {
$lis = "";
$optManVars = "";
$optVars = "";
@@ -61,36 +59,36 @@ class Page_mail_templates extends Page
}
}
- protected function doRender()
+ public static function doRender()
{
- $this->enrichHtml();
+ self::enrichHtml();
Render::addTemplate('templates', [
- 'templates' => $this->templates,
+ 'templates' => self::$templates,
'allowedReset' => User::hasPermission("templates.reset"),
'allowedSave' => User::hasPermission("templates.save"),
]);
}
- private function forcmp($string)
+ private static function forcmp($string)
{
return trim(str_replace("\r\n", "\n", $string));
}
- private function handleSave()
+ private static function handleSave()
{
$data = Request::post('templates');
if (is_array($data)) {
- $this->fetchTemplates();
- foreach ($this->templates as &$template) {
+ self::fetchTemplates();
+ foreach (self::$templates as &$template) {
if (isset($data[$template['name']])) {
- if ($this->forcmp($template['template']) !== $this->forcmp($data[$template['name']]['template'])) {
+ if (self::forcmp($template['template']) !== self::forcmp($data[$template['name']]['template'])) {
if (empty($template['original_template'])) {
$template['original_template'] = $template['template'];
}
$template['edit_version'] = $template['version'];
}
$template['original'] = (empty($template['original_template']) && $template['original'])
- || $this->forcmp($template['original_template']) === $this->forcmp($data[$template['name']]['template']);
+ || self::forcmp($template['original_template']) === self::forcmp($data[$template['name']]['template']);
if ($template['original']) {
$template['original_template'] = '';
}
@@ -98,7 +96,7 @@ class Page_mail_templates extends Page
}
}
unset($template);
- $data = json_encode(array('templates' => $this->templates));
+ $data = json_encode(array('templates' => self::$templates));
Database::exec("UPDATE sat.configuration SET value = :value WHERE parameter = 'templates'", array('value' => $data));
Message::addSuccess('templates-saved');
} else {
@@ -107,7 +105,7 @@ class Page_mail_templates extends Page
Util::redirect('?do=dozmod&section=templates');
}
- private function handleReset()
+ private static function handleReset()
{
$result = Download::asStringPost('http://127.0.0.1:9080/do/reset-mail-templates', array(), 10, $code);
if ($code == 999) {
@@ -120,17 +118,22 @@ class Page_mail_templates extends Page
Util::redirect('?do=dozmod&section=templates');
}
- private function fetchTemplates() {
+ private static function fetchTemplates() {
$templates= Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'templates'));
if ($templates != null) {
$templates = @json_decode($templates['value'], true);
if (is_array($templates)) {
- $names = array_map(function ($e) { return $e['name']; }, $templates['templates']);
+ $names = array_map(static function ($e) { return $e['name']; }, $templates['templates']);
array_multisort($names, SORT_ASC, $templates['templates']);
- $this->templates = $templates['templates'];
+ self::$templates = $templates['templates'];
}
}
}
+ public static function doAjax()
+ {
+
+ }
+
}
diff --git a/modules-available/dozmod/inc/pagedozmodusers.inc.php b/modules-available/dozmod/pages/users.inc.php
index f4ac852b..50f0f763 100644
--- a/modules-available/dozmod/inc/pagedozmodusers.inc.php
+++ b/modules-available/dozmod/pages/users.inc.php
@@ -1,31 +1,32 @@
<?php
-class Page_dozmod_users extends Page
+class SubPage
{
- protected function doPreprocess()
+ public static function doPreprocess()
{
-
+ // Currently there's only one view, actions are ajax
+ User::assertPermission('users.view');
}
- protected function doRender()
+ public static function doRender()
{
- $this->listUsers();
- $this->listOrganizations();
+ self::listUsers();
+ self::listOrganizations();
}
- protected function doAjax()
+ public static function doAjax()
{
User::load();
$action = Request::post('action', '', 'string');
if ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') {
if (User::hasPermission("users.".$action)) {
- $this->setUserOption($action);
+ self::setUserOption($action);
}
} elseif ($action === 'setorglogin') {
- if (User::hasPermission("users.orglogin")) {
- $this->setOrgOption($action);
+ if (User::hasPermission("users.setorglogin")) {
+ self::setOrgOption($action);
}
} else {
die('No such action');
@@ -34,7 +35,7 @@ class Page_dozmod_users extends Page
// Helpers
- private function listUsers()
+ private static function listUsers()
{
$res = Database::simpleQuery('SELECT userid, firstname, lastname, email, lastlogin, user.canlogin, issuperuser, emailnotifications,'
. ' organization.displayname AS orgname FROM sat.user'
@@ -42,35 +43,41 @@ class Page_dozmod_users extends Page
. ' ORDER BY lastname ASC, firstname ASC');
$rows = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $row['canlogin'] = $this->checked($row['canlogin']);
- $row['issuperuser'] = $this->checked($row['issuperuser']);
- $row['emailnotifications'] = $this->checked($row['emailnotifications']);
- $row['lastlogin'] = date('d.m.Y', $row['lastlogin']);
+ settype($row['lastlogin'], 'int');
+ $row['canlogin'] = self::checked($row['canlogin']);
+ $row['issuperuser'] = self::checked($row['issuperuser']);
+ $row['emailnotifications'] = self::checked($row['emailnotifications']);
+ if ($row['lastlogin'] !== 0) {
+ $row['lastlogin_s'] = date('d.m.Y', $row['lastlogin']);
+ }
$rows[] = $row;
}
- Render::addTemplate('userlist', array('users' => $rows));
+ Render::addTemplate('userlist', array(
+ 'users' => $rows,
+ 'nameTag' => User::hasPermission('actionlog.view') ? 'a' : 'span',
+ ));
}
- private function listOrganizations()
+ private static function listOrganizations()
{
$res = Database::simpleQuery('SELECT organizationid, displayname, canlogin FROM sat.organization'
. ' ORDER BY displayname ASC');
$rows = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $row['canlogin'] = $this->checked($row['canlogin']);
+ $row['canlogin'] = self::checked($row['canlogin']);
$rows[] = $row;
}
Render::addTemplate('orglist', array('organizations' => $rows));
}
- private function checked($val)
+ private static function checked($val)
{
if ($val)
return 'checked="checked"';
return '';
}
- private function setUserOption($option)
+ private static function setUserOption($option)
{
$val = (string) Request::post('value', '-');
if ($val !== '1' && $val !== '0')
@@ -97,7 +104,7 @@ class Page_dozmod_users extends Page
die($val);
}
- private function setOrgOption($option)
+ private static function setOrgOption($option)
{
$val = (string) Request::post('value', '-');
if ($val !== '1' && $val !== '0')
@@ -118,4 +125,4 @@ class Page_dozmod_users extends Page
die($val);
}
-} \ No newline at end of file
+}
diff --git a/modules-available/dozmod/permissions/permissions.json b/modules-available/dozmod/permissions/permissions.json
index e8dfb558..c8958089 100644
--- a/modules-available/dozmod/permissions/permissions.json
+++ b/modules-available/dozmod/permissions/permissions.json
@@ -1,14 +1,59 @@
-[
- "images.delete",
- "mail.save",
- "mail.testmail",
- "runtimeconfig.save",
- "templates.save",
- "templates.reset",
- "users.setmail",
- "users.setlogin",
- "users.setsu",
- "users.orglogin",
- "log.showuser",
- "log.showtarget"
-] \ No newline at end of file
+{
+ "expiredimages.delete": {
+ "location-aware": false
+ },
+ "actionlog.view": {
+ "location-aware": false
+ },
+ "ldapfilters.view": {
+ "location-aware": false
+ },
+ "ldapfilters.save": {
+ "location-aware": false
+ },
+ "mailconfig.save": {
+ "location-aware": false
+ },
+ "networkrules.view": {
+ "location-aware": false
+ },
+ "networkrules.save": {
+ "location-aware": false
+ },
+ "networkshares.view": {
+ "location-aware": false
+ },
+ "networkshares.save": {
+ "location-aware": false
+ },
+ "runtimeconfig.save": {
+ "location-aware": false
+ },
+ "runscripts.view": {
+ "location-aware": false
+ },
+ "runscripts.save": {
+ "location-aware": false
+ },
+ "templates.reset": {
+ "location-aware": false
+ },
+ "templates.save": {
+ "location-aware": false
+ },
+ "users.setorglogin": {
+ "location-aware": false
+ },
+ "users.setlogin": {
+ "location-aware": false
+ },
+ "users.setmail": {
+ "location-aware": false
+ },
+ "users.setsu": {
+ "location-aware": false
+ },
+ "users.view": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/dozmod/style.css b/modules-available/dozmod/style.css
index 23dd121e..4cec715a 100644
--- a/modules-available/dozmod/style.css
+++ b/modules-available/dozmod/style.css
@@ -48,4 +48,24 @@
.table > tbody > tr > td > div {
display: inline-block;
+}
+
+/* number of columns in tree view depending on screen size */
+.column-list {
+ column-gap: 20px;
+ column-count: 2;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+
+@media (min-width: 768px) {
+ .column-list {
+ column-count: 3;
+ }
+}
+
+@media (min-width: 992px) {
+ .column-list {
+ column-count: 4;
+ }
} \ No newline at end of file
diff --git a/modules-available/dozmod/templates/actionlog-log.html b/modules-available/dozmod/templates/actionlog-log.html
index 8aa57207..7caa3d34 100644
--- a/modules-available/dozmod/templates/actionlog-log.html
+++ b/modules-available/dozmod/templates/actionlog-log.html
@@ -18,7 +18,9 @@
{{#showActor}}
<td style="min-width:140px">
{{#uuserid}}
- {{#allowedShowUser}}<a href="?do=dozmod&amp;section=actionlog&amp;action=showuser&amp;uuid={{uuserid}}">{{/allowedShowUser}} {{ulastname}}, {{ufirstname}}{{#allowedShowUser}}</a>{{/allowedShowUser}}
+ <a href="?do=dozmod&amp;section=actionlog&amp;action=showuser&amp;uuid={{uuserid}}">
+ {{ulastname}}, {{ufirstname}}
+ </a>
{{/uuserid}}
{{^uuserid}}
{{lang_system}}
@@ -28,7 +30,7 @@
{{#showTarget}}
<td style="word-wrap: break-word">
{{#targeturl}}
- {{#allowedShowTarget}}<a href="{{targeturl}}">{{/allowedShowTarget}}{{targetname}}{{#allowedShowTarget}}</a>{{/allowedShowTarget}}
+ <a href="{{targeturl}}">{{targetname}}</a>
{{/targeturl}}
{{^targeturl}}
{{targetname}}
diff --git a/modules-available/dozmod/templates/images-delete.html b/modules-available/dozmod/templates/images-delete.html
index ed75a0d2..78690426 100644
--- a/modules-available/dozmod/templates/images-delete.html
+++ b/modules-available/dozmod/templates/images-delete.html
@@ -9,6 +9,7 @@
<div class="table-responsive">
<form id="delform" method="post" action="?do=DozMod" onsubmit="return slxPostdel()">
<input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="section" value="expiredimages">
<input type="hidden" name="action" value="delimages">
<table class="table table-stripped table-condensed stupidtable">
<thead>
diff --git a/modules-available/dozmod/templates/ldapfilter-add.html b/modules-available/dozmod/templates/ldapfilter-add.html
new file mode 100644
index 00000000..f66972d1
--- /dev/null
+++ b/modules-available/dozmod/templates/ldapfilter-add.html
@@ -0,0 +1,39 @@
+<h1>{{lang_ldapfilters}}</h1>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_ldapFilterEdit}}
+ </div>
+ <div class="panel-body">
+
+ <p>{{lang_ldapFilterDescription}}</p>
+ <form method="post" action="?do=dozmod&section=ldapfilters">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" id="filterid" name="filterid" value="{{filterid}}">
+
+ <div class="input-group">
+ <label class="input-group-addon" for="filtername">{{lang_ldapFilterName}}</label>
+ <input type="text" name="filtername" id ="filtername" class="form-control" placeholder="" value="{{filtername}}" required>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="attribute">{{lang_ldapFilterAttribute}}</label>
+ <input type="text" name="attribute" id ="attribute" class="form-control" placeholder="" value="{{filterkey}}" required>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="value">{{lang_ldapFilterValue}}</label>
+ <input type="text" name="value" id ="value" class="form-control" placeholder="" value="{{filtervalue}}" required>
+ </div>
+
+ <div class="text-right" style="margin-top: 20px;">
+ <a type="button" class="btn btn-default" href="?do=dozmod&section=ldapfilters">{{lang_cancel}}</a>
+ <button class="btn btn-primary" type="submit" name="action" value="saveFilter">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ </form>
+ </div>
+</div>
+
+<script type="text/javascript">
+</script>
diff --git a/modules-available/dozmod/templates/ldapfilters.html b/modules-available/dozmod/templates/ldapfilters.html
new file mode 100644
index 00000000..824ec70b
--- /dev/null
+++ b/modules-available/dozmod/templates/ldapfilters.html
@@ -0,0 +1,77 @@
+<h1>{{lang_ldapfilters}}</h1>
+
+<p>
+ {{lang_ldapfiltersIntro}}
+</p>
+
+<table class="table">
+ <thead>
+ <tr>
+ <th class="">{{lang_ldapFilterName}}</th>
+ <th class="">{{lang_ldapFilterAttribute}}</th>
+ <th class="">{{lang_ldapFilterValue}}</th>
+ {{#hasEditPermission}}
+ <th class="slx-smallcol">{{lang_edit}}</th>
+ <th class="slx-smallcol">{{lang_delete}}</th>
+ {{/hasEditPermission}}
+ </tr>
+ </thead>
+ <tbody>
+ {{#ldapfilters}}
+ <tr>
+ <td>{{filtername}}</td>
+ <td>{{filterkey}}</td>
+ <td>{{filtervalue}}</td>
+ {{#hasEditPermission}}
+ <td class="text-center">
+ <a class="btn btn-xs btn-primary" href="?do=dozmod&section=ldapfilters&show=edit&filterid={{filterid}}">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ </td>
+ <td class="text-center">
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="setDeleteId('{{filterid}}')">
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ </td>
+ {{/hasEditPermission}}
+ </tr>
+ {{/ldapfilters}}
+ </tbody>
+</table>
+
+{{#hasEditPermission}}
+<div class="text-right">
+ <a class="btn btn-sm btn-success" href="?do=dozmod&section=ldapfilters&show=edit">
+ <span class="glyphicon glyphicon-plus"></span>
+ {{lang_ldapFilterAdd}}
+ </a>
+</div>
+{{/hasEditPermission}}
+
+<form method="post" action="?do=dozmod&section=ldapfilters">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" id="deleteAction" name="filterid" value="">
+ <div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_ldapFilterDeleteConfirmation}}</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="deleteFilter" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+
+<script type="text/javascript">
+function setDeleteId(id) {
+ $('#deleteAction').val(id)
+}
+</script>
diff --git a/modules-available/dozmod/templates/mailconfig.html b/modules-available/dozmod/templates/mailconfig.html
index d5d4db29..dbcdddcb 100644
--- a/modules-available/dozmod/templates/mailconfig.html
+++ b/modules-available/dozmod/templates/mailconfig.html
@@ -55,13 +55,14 @@
</div>
<br>
<div class="text-right">
- <button {{^allowedTest}}disabled{{/allowedTest}} class="btn btn-warning" type="button" id="test-button" name="button" value="test" onclick="slxTestConfig()"><span class="glyphicon glyphicon-envelope"></span> {{lang_test}}</button>
+ <button {{perms.mailconfig.save.disabled}} class="btn btn-warning" type="button" id="test-button" name="button" value="test" onclick="slxTestConfig()"><span class="glyphicon glyphicon-envelope"></span> {{lang_test}}</button>
<span id="test-spin" style="display:none"><span class="glyphicon glyphicon-refresh slx-rotation"></span></span>
- <pre id="test-output" style="display:none"></pre>
- <button {{^allowedSave}}disabled{{/allowedSave}} class="btn btn-primary" type="submit" name="button" value="save"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <pre id="test-output" style="display:none;text-align:left"></pre>
+ <button {{perms.mailconfig.save.disabled}} class="btn btn-primary" type="submit" name="button" value="save"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
<br>
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="mail">
+ <input type="hidden" name="section" value="mailconfig">
</div>
</form>
</div>
diff --git a/modules-available/dozmod/templates/networkrules-edit.html b/modules-available/dozmod/templates/networkrules-edit.html
new file mode 100644
index 00000000..c04e2825
--- /dev/null
+++ b/modules-available/dozmod/templates/networkrules-edit.html
@@ -0,0 +1,43 @@
+<h1>{{lang_networkrules}}</h1>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_editNetworkrule}}
+ </div>
+ <div class="panel-body">
+ <form method="post" action="?do=dozmod">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="section" value="networkrules">
+ <input type="hidden" name="ruleid" value="{{ruleid}}">
+
+ <div class="input-group">
+ <label class="input-group-addon" for="rulename">{{lang_name}}</label>
+ <input required type="text" name="rulename" id="rulename" class="form-control" value="{{rulename}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="host">{{lang_host}}</label>
+ <input required type="text" name="host" id="host" class="form-control" value="{{host}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="port">{{lang_port}}</label>
+ <input required type="number" name="port" id="port" class="form-control" value="{{port}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="direction">{{lang_direction}}</label>
+ <select class="form-control" name="direction" id="direction">
+ <option {{inSelected}} value="IN">IN</option>
+ <option {{outSelected}} value="OUT">OUT</option>
+ </select>
+ </div>
+ <div class="text-right" style="margin-top: 20px">
+ <a href="?do=dozmod&amp;section=networkrules" class="btn btn-default">
+ {{lang_cancel}}
+ </a>
+ <button type="submit" class="btn btn-primary" name="action" value="save">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ </form>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules-available/dozmod/templates/networkrules.html b/modules-available/dozmod/templates/networkrules.html
new file mode 100644
index 00000000..4344ff4f
--- /dev/null
+++ b/modules-available/dozmod/templates/networkrules.html
@@ -0,0 +1,82 @@
+<h1>{{lang_networkrules}}</h1>
+
+<p>
+ {{lang_networkrulesIntro}}
+</p>
+
+<table class="table">
+ <thead>
+ <tr>
+ <th>{{lang_name}}</th>
+ <th>{{lang_host}}</th>
+ <th>{{lang_port}}</th>
+ <th>{{lang_direction}}</th>
+ {{#hasEditPermissions}}
+ <th class="slx-smallcol">{{lang_edit}}</th>
+ <th class="slx-smallcol">{{lang_delete}}</th>
+ {{/hasEditPermissions}}
+ </tr>
+ </thead>
+ <tbody>
+ {{#networkrules}}
+ <tr>
+ <td>{{rulename}}</td>
+ <td>{{host}}</td>
+ <td>{{port}}</td>
+ <td>{{direction}}</td>
+ {{#hasEditPermissions}}
+ <td align="center">
+ <a href="?do=dozmod&amp;section=networkrules&amp;show=edit&amp;ruleid={{ruleid}}" class="btn btn-xs btn-primary">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ </td>
+ <td align="center">
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="deleteRule('{{ruleid}}')">
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ </td>
+ {{/hasEditPermissions}}
+ </tr>
+ {{/networkrules}}
+ </tbody>
+</table>
+{{#hasEditPermissions}}
+<div class="text-right">
+ <a href="?do=dozmod&amp;section=networkrules&amp;show=edit" class="btn btn-success">
+ <span class="glyphicon glyphicon-plus"></span>
+ {{lang_addRule}}
+ </a>
+</div>
+{{/hasEditPermissions}}
+
+<!-- Modals -->
+<form method="post" action="?do=dozmod">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="section" value="networkrules">
+ <div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_ruleDeleteConfirm}}</p>
+ </div>
+ <div class="modal-footer">
+ <input type="hidden" id="delete-rule-id" name="ruleid" value="">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="delete" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+
+<script type="text/javascript">
+
+ function deleteRule(ruleid) {
+ $("#delete-rule-id").val(ruleid);
+ }
+
+</script> \ No newline at end of file
diff --git a/modules-available/dozmod/templates/networkshares-edit.html b/modules-available/dozmod/templates/networkshares-edit.html
new file mode 100644
index 00000000..f0b43837
--- /dev/null
+++ b/modules-available/dozmod/templates/networkshares-edit.html
@@ -0,0 +1,84 @@
+<h1>{{lang_networkshares}}</h1>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_editNetworkshare}}
+ </div>
+ <div class="panel-body">
+ <form method="post" action="?do=dozmod">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="section" value="networkshares">
+ <input type="hidden" name="shareid" value="{{shareid}}">
+
+ <div class="input-group">
+ <label class="input-group-addon" for="name">{{lang_name}}</label>
+ <input required type="text" name="sharename" id="name" class="form-control" value="{{sharename}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="path">{{lang_path}}</label>
+ <input required type="text" name="path" id="path" class="form-control" value="{{path}}">
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="target">{{lang_target}}</label>
+ <select class="form-control" name="target" id="target">
+ <option value="-">{{lang_none}}</option>
+ <option value="D">D:</option><option value="E">E:</option><option value="F">F:</option>
+ <option value="G">G:</option><option value="H">H:</option><option value="I">I:</option>
+ <option value="J">J:</option><option value="K">K:</option><option value="L">L:</option>
+ <option value="M">M:</option><option value="N">N:</option><option value="O">O:</option>
+ <option value="P">P:</option><option value="Q">Q:</option><option value="R">R:</option>
+ <option value="S">S:</option><option value="T">T:</option><option value="U">U:</option>
+ <option value="V">V:</option><option value="W">W:</option><option value="X">X:</option>
+ <option value="Y">Y:</option><option value="Z">Z:</option>
+ <option value="PRINTER">{{lang_printer}}</option>
+ </select>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="auth">{{lang_authMethod}}</label>
+ <select class="form-control" name="auth" id="auth">
+ <option value="LOGIN_USER" {{loggedInUser_selected}}>{{lang_loggedInUser}}</option>
+ <option value="OTHER_USER" {{specificUser_selected}}>{{lang_specificUser}}</option>
+ </select>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="username">{{lang_username}}</label>
+ <input required type="text" name="username" id="username" class="form-control" value="{{username}}" {{#loggedInUser_selected}}disabled{{/loggedInUser_selected}}>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="password">{{lang_password}}</label>
+ <input required type="{{password_type}}" name="password" id="password" class="form-control" value="{{password}}" {{#loggedInUser_selected}}disabled{{/loggedInUser_selected}}>
+ </div>
+ <div class="text-right" style="margin-top: 20px">
+ <a href="?do=dozmod&amp;section=networkshares" class="btn btn-default">
+ {{lang_cancel}}
+ </a>
+ <button type="submit" class="btn btn-primary" name="action" value="save">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ </form>
+ </div>
+</div>
+
+<script type="text/javascript">
+
+ document.addEventListener("DOMContentLoaded", function () {
+
+ $('#target').val('{{mountpoint}}');
+
+ $('#auth').change(function () {
+ var username = $('#username');
+ var password = $('#password');
+ if ($(this).val() === 'OTHER_USER') {
+ username.prop('disabled', false);
+ password.prop('disabled', false);
+ } else {
+ username.prop('disabled', true);
+ password.prop('disabled', true);
+ }
+ }).change();
+
+ })
+
+</script> \ No newline at end of file
diff --git a/modules-available/dozmod/templates/networkshares.html b/modules-available/dozmod/templates/networkshares.html
new file mode 100644
index 00000000..aaafa256
--- /dev/null
+++ b/modules-available/dozmod/templates/networkshares.html
@@ -0,0 +1,113 @@
+<h1>{{lang_networkshares}}</h1>
+
+<p>
+ {{lang_networksharesIntro}}
+</p>
+
+<table class="table">
+ <thead>
+ <tr>
+ <th>{{lang_name}}</th>
+ <th>{{lang_path}}</th>
+ <th>{{lang_target}}</th>
+ <th>{{lang_authMethod}}</th>
+ <th>{{lang_username}}</th>
+ {{#hasEditPermissions}}
+ <th class="slx-smallcol">{{lang_active}}</th>
+ <th class="slx-smallcol">{{lang_edit}}</th>
+ <th class="slx-smallcol">{{lang_delete}}</th>
+ {{/hasEditPermissions}}
+ </tr>
+ </thead>
+ <tbody>
+ {{#networkshares}}
+ <tr>
+ <td>{{sharename}}</td>
+ <td>{{path}}</td>
+ <td>{{mountpoint}}</td>
+ <td>
+ {{#loginAsUser}}{{lang_loggedInUser}}{{/loginAsUser}}
+ {{^loginAsUser}}{{lang_specificUser}}{{/loginAsUser}}
+ </td>
+ <td>
+ {{^loginAsUser}}{{username}}{{/loginAsUser}}
+ </td>
+ {{#hasEditPermissions}}
+ <td class="text-nowrap">
+ <form method="post" action="?do=dozmod">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="section" value="networkshares">
+ <input type="hidden" name="shareid" value="{{shareid}}">
+ {{#active}}
+ <span class="glyphicon glyphicon-ok text-success"></span>
+ <button type="submit" name="action" value="deactivate" class="btn btn-xs btn-default">
+ <span class="glyphicon glyphicon-remove"></span>
+ </button>
+ {{/active}}
+ {{^active}}
+ <span class="glyphicon glyphicon-remove text-danger"></span>
+ <button type="submit" name="action" value="activate" class="btn btn-xs btn-default">
+ <span class="glyphicon glyphicon-ok"></span>
+ </button>
+ {{/active}}
+ </form>
+ </td>
+ <td align="center">
+ <a href="?do=dozmod&amp;section=networkshares&amp;show=edit&amp;shareid={{shareid}}" class="btn btn-xs btn-primary">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ </td>
+ <td align="center">
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="deleteShare('{{shareid}}')">
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ </td>
+ {{/hasEditPermissions}}
+ </tr>
+ {{/networkshares}}
+ </tbody>
+</table>
+{{#hasEditPermissions}}
+<div class="text-right">
+ <a href="?do=dozmod&amp;section=networkshares&amp;show=edit" class="btn btn-success {{allowAddShare}}">
+ <span class="glyphicon glyphicon-plus"></span>
+ {{lang_addShare}}
+ </a>
+</div>
+{{/hasEditPermissions}}
+
+<!-- Modals -->
+<form method="post" action="?do=dozmod">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="section" value="networkshares">
+ <div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_shareDeleteConfirm}}</p>
+ </div>
+ <div class="modal-footer">
+ <input type="hidden" id="delete-share-id" name="shareid" value="">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="delete" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+
+<script type="text/javascript">
+
+ function deleteShare(shareid) {
+ $("#delete-share-id").val(shareid);
+ }
+
+ document.addEventListener("DOMContentLoaded", function () {
+
+ })
+
+</script> \ No newline at end of file
diff --git a/modules-available/dozmod/templates/runscripts-edit.html b/modules-available/dozmod/templates/runscripts-edit.html
new file mode 100644
index 00000000..8d81b33c
--- /dev/null
+++ b/modules-available/dozmod/templates/runscripts-edit.html
@@ -0,0 +1,89 @@
+<h1>{{lang_scriptsHead}}</h1>
+
+<form method="post" action="?do=dozmod&section=runscripts">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" id="runscriptid" name="runscriptid" value="{{runscriptid}}">
+
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_editScript}}
+ </div>
+ <div class="panel-body">
+ <div class="input-group">
+ <label class="input-group-addon" for="scriptname">{{lang_name}}</label>
+ <input type="text" name="scriptname" id="scriptname" class="form-control"
+ value="{{scriptname}}" required>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="extension">{{lang_scriptExtension}}</label>
+ <input type="text" name="extension" id="extension" class="form-control" value="{{extension}}"
+ list="default-exts">
+ <datalist id="default-exts">
+ <option value="bat">
+ <option value="ps">
+ <option value="py">
+ <option value="sh">
+ </datalist>
+ </div>
+ <div class="input-group">
+ <label class="input-group-addon" for="visibility">{{lang_scriptVisibility}}</label>
+ <select type="text" name="visibility" id="visibility" class="form-control" required>
+ <option value="0" {{visibility_0_selected}}>{{lang_hidden}}</option>
+ <option value="1" {{visibility_1_selected}}>{{lang_normal}}</option>
+ <option value="2" {{visibility_2_selected}}>{{lang_minimized}}</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <div class="checkbox">
+ <input type="checkbox" name="passcreds" value="1" {{passcreds_checked}} id="passcreds"
+ class="form-control">
+ <label for="passcreds">
+ {{lang_scriptPassCredentials}}
+ </label>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="radio">
+ <input type="radio" name="isglobal" value="1" {{isglobal_1_checked}} id="isglobal1" class="form-control">
+ <label for="isglobal1">
+ {{lang_scriptIsGlobal}}
+ </label>
+ </div>
+ <div class="radio">
+ <input type="radio" name="isglobal" value="0" {{isglobal_0_checked}} id="isglobal0" class="form-control">
+ <label for="isglobal0">
+ {{lang_scriptIsPredefined}}
+ </label>
+ </div>
+ </div>
+ <div>
+ <label for="content">{{lang_scriptContent}}</label>
+ <textarea name="content" id="content" rows="20" cols="80" class="form-control">{{content}}</textarea>
+ </div>
+
+ <div class="panel panel-body column-list">
+ {{#oslist}}
+ <div class="checkbox">
+ <input type="checkbox" name="osid[]" value="{{osid}}" {{checked}} id="osid{{osid}}" class="form-control">
+ <label for="osid{{osid}}">
+ {{displayname}}
+ </label>
+ </div>
+ {{/oslist}}
+ </div>
+
+ <div class="text-right" style="margin-top: 20px;">
+ <a type="button" class="btn btn-default" href="?do=dozmod&section=runscripts">{{lang_cancel}}</a>
+ <button class="btn btn-primary" type="submit" name="action" value="save">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+
+ </div>
+ </div>
+
+</form>
+
+<script type="text/javascript">
+</script>
diff --git a/modules-available/dozmod/templates/runscripts-list.html b/modules-available/dozmod/templates/runscripts-list.html
new file mode 100644
index 00000000..4d519afb
--- /dev/null
+++ b/modules-available/dozmod/templates/runscripts-list.html
@@ -0,0 +1,89 @@
+<h1>{{lang_scriptsHead}}</h1>
+
+<p>
+ {{lang_scriptsIntro}}
+</p>
+
+<table class="table">
+ <thead>
+ <tr>
+ <th>{{lang_name}}</th>
+ <th class="slx-smallcol">{{lang_scriptExtensionHead}}</th>
+ <th class="slx-smallcol">{{lang_scriptVisibilityHead}}</th>
+ <th class="slx-smallcol">{{lang_scriptPassCredentialsHead}}</th>
+ <th class="slx-smallcol">{{lang_scriptIsGlobalHead}}</th>
+ {{#hasEditPermission}}
+ <th class="slx-smallcol">{{lang_edit}}</th>
+ <th class="slx-smallcol">{{lang_delete}}</th>
+ {{/hasEditPermission}}
+ </tr>
+ </thead>
+ <tbody>
+ {{#list}}
+ <tr>
+ <td>{{scriptname}}</td>
+ <td>.{{extension}}</td>
+ <td><span class="glyphicon glyphicon-{{visibility}}"></span></td>
+ <td>
+ {{#passcreds}}
+ <span class="glyphicon glyphicon-ok"></span>
+ {{/passcreds}}
+ </td>
+ <td>
+ {{#isglobal}}
+ <span class="glyphicon glyphicon-ok"></span>
+ {{/isglobal}}
+ </td>
+ {{#hasEditPermission}}
+ <td class="text-center">
+ <a class="btn btn-xs btn-primary" href="?do=dozmod&amp;section=runscripts&amp;show=edit&amp;runscriptid={{runscriptid}}">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ </td>
+ <td class="text-center">
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="setDeleteId('{{runscriptid}}')">
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ </td>
+ {{/hasEditPermission}}
+ </tr>
+ {{/list}}
+ </tbody>
+</table>
+
+{{#hasEditPermission}}
+ <div class="text-right">
+ <a class="btn btn-sm btn-success" href="?do=dozmod&amp;section=runscripts&amp;show=edit&amp;runscriptid=0">
+ <span class="glyphicon glyphicon-plus"></span>
+ {{lang_runScriptAdd}}
+ </a>
+ </div>
+{{/hasEditPermission}}
+
+<form method="post" action="?do=dozmod&amp;section=runscripts">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" id="deleteAction" name="runscriptid" value="">
+ <div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_runScriptDeleteConfirmation}}</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="delete" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+
+<script type="text/javascript">
+ function setDeleteId(id) {
+ $('#deleteAction').val(id)
+ }
+</script>
diff --git a/modules-available/dozmod/templates/runtimeconfig.html b/modules-available/dozmod/templates/runtimeconfig.html
index 1d4cc6cb..6ea65ad4 100644
--- a/modules-available/dozmod/templates/runtimeconfig.html
+++ b/modules-available/dozmod/templates/runtimeconfig.html
@@ -20,13 +20,13 @@
<div class="checkbox">
<input type="checkbox" name="defaultLecturePermissions[admin]" value="1" {{defaultLecturePermissions.admin}} id ="lecture_admin" class="form-control">
- <label>
+ <label for"lecture_admin">
{{lang_lecturePermissionAdmin}}
</label>
</div>
<div class="checkbox">
<input type="checkbox" name="defaultLecturePermissions[edit]" value="1" {{defaultLecturePermissions.edit}} id ="lecture_edit" class="form-control">
- <label>
+ <label for="lecture_edit">
{{lang_lecturePermissionEdit}}
</label>
</div>
@@ -116,6 +116,7 @@
<br>
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="runtime">
+ <input type="hidden" name="section" value="runtimeconfig">
<div class="text-right">
<button {{^allowedSave}}disabled{{/allowedSave}} class="btn btn-primary" type="submit" name="button" value="save"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
diff --git a/modules-available/dozmod/templates/templates.html b/modules-available/dozmod/templates/templates.html
index 3ee0ccbc..721de375 100644
--- a/modules-available/dozmod/templates/templates.html
+++ b/modules-available/dozmod/templates/templates.html
@@ -8,7 +8,7 @@
<p><i>{{lang_templatePageDescription}}</i></p>
- <form id="templateForm" role="form" method="POST" action="?do=dozmod&amp;section=templates">
+ <form id="templateForm" role="form" method="POST" action="?do=dozmod&amp;section=templates" onsubmit="return validateForm()">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="save">
@@ -80,7 +80,7 @@
{{/templates}}
</div>
- <button {{^allowedSave}}disabled{{/allowedSave}} type="submit" onclick="return validateForm()" class="btn btn-primary pull-right"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button {{^allowedSave}}disabled{{/allowedSave}} type="submit" class="btn btn-primary pull-right"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</form>
<form method="POST" action="?do=dozmod&amp;section=templates">
<input type="hidden" name="token" value="{{token}}">
@@ -138,7 +138,7 @@ function validateForm() {
var missing = [];
mandatory.forEach(function (v,i) {
- if (value.indexOf("%" + v + "%") == -1) {
+ if (value.indexOf("%" + v + "%") === -1) {
missing.push(v);
}
});
@@ -155,6 +155,7 @@ function validateForm() {
if ($toppest === false || $toppest.offset().top > $frame.offset().top) {
$toppest = $frame;
}
+ $('#panel_' + setting).collapse('show');
/* overall result */
ok = false;
} else {
diff --git a/modules-available/dozmod/templates/userlist.html b/modules-available/dozmod/templates/userlist.html
index b8080b44..6b19907d 100644
--- a/modules-available/dozmod/templates/userlist.html
+++ b/modules-available/dozmod/templates/userlist.html
@@ -22,9 +22,13 @@
<tbody>
{{#users}}
<tr>
- <td class="text-left text-nowrap"><a href="?do=dozmod&amp;section=actionlog&amp;action=showuser&amp;uuid={{userid}}">{{lastname}}, {{firstname}}</a></td>
+ <td class="text-left text-nowrap">
+ <{{nameTag}} href="?do=dozmod&amp;section=actionlog&amp;action=showuser&amp;uuid={{userid}}">
+ {{lastname}}, {{firstname}}
+ </{{nameTag}}>
+ </td>
<td class="text-left text-nowrap">{{orgname}}</td>
- <td class="text-left text-nowrap">{{lastlogin}}</td>
+ <td class="text-left text-nowrap" data-sort-value="{{lastlogin}}">{{lastlogin_s}}</td>
<td class="text-left text-nowrap"><a href="mailto:{{email}}">{{email}}</a></td>
<td>
<div class="checkbox">
diff --git a/modules-available/eventlog/config.json b/modules-available/eventlog/config.json
index 6778348d..aa23adb5 100644
--- a/modules-available/eventlog/config.json
+++ b/modules-available/eventlog/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.status"
-}
+ "category": "main.status"
+} \ No newline at end of file
diff --git a/modules-available/eventlog/page.inc.php b/modules-available/eventlog/page.inc.php
index 320c3b07..1c81983c 100644
--- a/modules-available/eventlog/page.inc.php
+++ b/modules-available/eventlog/page.inc.php
@@ -6,43 +6,26 @@ class Page_EventLog extends Page
protected function doPreprocess()
{
User::load();
- if (!User::isLoggedIn()) {
- Message::addError('main.no-permission');
- Util::redirect('?do=Main');
- }
- if (User::hasPermission("view")) {
- User::setLastSeenEvent(Property::getLastWarningId());
- }
+ User::assertPermission('view');
+ User::setLastSeenEvent(Property::getLastWarningId());
}
protected function doRender()
{
Render::addTemplate("heading");
- if (User::hasPermission("view")) {
- $today = date('d.m.Y');
- $yesterday = date('d.m.Y', time() - 86400);
- $lines = array();
- $paginate = new Paginate("SELECT logid, dateline, logtypeid, description, extra FROM eventlog ORDER BY logid DESC", 50);
- $res = $paginate->exec();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $day = date('d.m.Y', $row['dateline']);
- if ($day === $today) {
- $day = Dictionary::translate('lang_today');
- } elseif ($day === $yesterday) {
- $day = Dictionary::translate('lang_yesterday');
- }
- $row['date'] = $day . date(' H:i', $row['dateline']);
- $row['icon'] = $this->typeToIcon($row['logtypeid']);
- $row['color'] = $this->typeToColor($row['logtypeid']);
- $lines[] = $row;
- }
-
- $paginate->render('_page', array(
- 'list' => $lines
- ));
- } else {
- Message::addError('main.no-permission');
+ $lines = array();
+ $paginate = new Paginate("SELECT logid, dateline, logtypeid, description, extra FROM eventlog ORDER BY logid DESC", 50);
+ $res = $paginate->exec();
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $row['date'] = Util::prettyTime($row['dateline']);
+ $row['icon'] = $this->typeToIcon($row['logtypeid']);
+ $row['color'] = $this->typeToColor($row['logtypeid']);
+ $lines[] = $row;
}
+
+ $paginate->render('_page', array(
+ 'list' => $lines
+ ));
}
private function typeToIcon($type)
diff --git a/modules-available/eventlog/permissions/permissions.json b/modules-available/eventlog/permissions/permissions.json
index f04ea714..a1748957 100644
--- a/modules-available/eventlog/permissions/permissions.json
+++ b/modules-available/eventlog/permissions/permissions.json
@@ -1,3 +1,5 @@
-[
- "view"
-] \ No newline at end of file
+{
+ "view": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/exams/baseconfig/getconfig.inc.php b/modules-available/exams/baseconfig/getconfig.inc.php
index 37a2caf4..10aa1d84 100644
--- a/modules-available/exams/baseconfig/getconfig.inc.php
+++ b/modules-available/exams/baseconfig/getconfig.inc.php
@@ -1,19 +1,28 @@
<?php
-$locations = ConfigHolder::get('SLX_LOCATIONS');
-if ($locations === false) {
- $locationIds = [];
-} else {
- $locationIds = explode(' ', $locations);
-}
-if (Exams::isInExamMode($locationIds, $lectureId, $autoLogin)) {
- ConfigHolder::add('SLX_EXAM', 'yes', 10000);
- if (strlen($lectureId) > 0) {
- ConfigHolder::add('SLX_EXAM_START', $lectureId, 10000);
+$foofoo = function($machineUuid) {
+ // Leave clients in any runmode alone
+ $res = Database::queryFirst('SELECT machineuuid FROM runmode WHERE machineuuid = :uuid',
+ array('uuid' => $machineUuid), true);
+ if (is_array($res))
+ return;
+ // Check if exam mode should apply
+ $locations = ConfigHolder::get('SLX_LOCATIONS');
+ if ($locations === false) {
+ $locationIds = [];
+ } else {
+ $locationIds = explode(' ', $locations);
}
- if (strlen($autoLogin) > 0) {
- ConfigHolder::add('SLX_AUTOLOGIN', $autoLogin, 10000);
+ if (Exams::isInExamMode($locationIds, $lectureId, $autoLogin)) {
+ ConfigHolder::add('SLX_EXAM', 'yes', 10000);
+ if (strlen($lectureId) > 0) {
+ ConfigHolder::add('SLX_EXAM_START', $lectureId, 10000);
+ }
+ if (strlen($autoLogin) > 0) {
+ ConfigHolder::add('SLX_AUTOLOGIN', $autoLogin, 10000);
+ }
+ ConfigHolder::add('SLX_SYSTEMD_TARGET', 'exam-mode', 10000);
}
- ConfigHolder::add('SLX_SYSTEMD_TARGET', 'exam-mode', 10000);
- ConfigHolder::add("SLX_PVS_HYBRID", false, 10000);
-}
+};
+
+$foofoo($uuid); \ No newline at end of file
diff --git a/modules-available/exams/config.json b/modules-available/exams/config.json
index 0780ebef..a99d1c1a 100644
--- a/modules-available/exams/config.json
+++ b/modules-available/exams/config.json
@@ -1,5 +1,12 @@
{
- "category":"main.content",
- "dependencies": [ "locations", "js_vis", "js_stupidtable", "bootstrap_datepicker", "bootstrap_timepicker", "bootstrap_multiselect"],
+ "category": "main.content",
+ "dependencies": [
+ "locations",
+ "js_vis",
+ "js_stupidtable",
+ "bootstrap_datepicker",
+ "bootstrap_timepicker",
+ "bootstrap_multiselect"
+ ],
"permission": "0"
-}
+} \ No newline at end of file
diff --git a/modules-available/exams/lang/de/permissions.json b/modules-available/exams/lang/de/permissions.json
index 3ead6249..b61be9a0 100644
--- a/modules-available/exams/lang/de/permissions.json
+++ b/modules-available/exams/lang/de/permissions.json
@@ -1,5 +1,4 @@
{
- "exams.add": "Neues Examen hinzufügen.",
- "exams.delete": "Examen löschen.",
- "exams.edit": "Examen bearbeiten."
-} \ No newline at end of file
+ "exams.view": "Geplante Prüfungen sehen.",
+ "exams.edit": "Prüfungen anlegen/editieren/löschen."
+}
diff --git a/modules-available/exams/lang/de/template-tags.json b/modules-available/exams/lang/de/template-tags.json
index 8bf37143..0fbaf0a1 100644
--- a/modules-available/exams/lang/de/template-tags.json
+++ b/modules-available/exams/lang/de/template-tags.json
@@ -1,5 +1,4 @@
{
- "lang_actions": "Aktionen",
"lang_addExam": "Zeitraum hinzuf\u00fcgen",
"lang_addingBasedOnLecture": "F\u00fcge neuen Pr\u00fcfungszeitraum basierend auf vorhandener Veranstaltung an",
"lang_allExamPeriods": "Alle Pr\u00fcfungszeitr\u00e4ume",
@@ -16,7 +15,6 @@
"lang_deleteConfirmation": "Wirklich l\u00f6schen?",
"lang_description": "Beschreibung",
"lang_duration": "Dauer",
- "lang_editExam": "Zeitraum bearbeiten",
"lang_end": "Ende",
"lang_end_date": "Ende Datum",
"lang_end_time": "Uhrzeit",
@@ -29,7 +27,7 @@
"lang_headingMain": "bwLehrpool Pr\u00fcfungsmodus",
"lang_id": "ID",
"lang_lectureName": "Veranstaltungsname",
- "lang_lectureOutOfRange": "Achtung: Start- bzw. Endzeitpunkt der Veranstaltung liegen au\u00dferhalb des oben angegebenen Zeitraums",
+ "lang_lectureOutOfRange": "Achtung: Der oben angegebene Zeitraum ist k\u00fcrzer als die Dauer der Veranstaltung",
"lang_location": "Raum\/Ort",
"lang_locationInfo": "W\u00e4hlen Sie hier die R\u00e4ume und Orte aus, die w\u00e4hrend des unten ausgew\u00e4hlten Zeitraums in den Pr\u00fcfungsmodus versetzt werden. Wenn sie hier keine Auswahl treffen, werden alle R\u00e4ume in den Pr\u00fcfungsmodus versetzt.",
"lang_locations": "R\u00e4ume\/Orte",
diff --git a/modules-available/exams/lang/en/permissions.json b/modules-available/exams/lang/en/permissions.json
index 3e14a761..70326fa9 100644
--- a/modules-available/exams/lang/en/permissions.json
+++ b/modules-available/exams/lang/en/permissions.json
@@ -1,5 +1,4 @@
{
- "exams.add": "Add new exam.",
- "exams.delete": "Delete exam.",
- "exams.edit": "Edit exam."
-} \ No newline at end of file
+ "exams.view": "View scheduled exams.",
+ "exams.edit": "Add/delete/edit exams."
+}
diff --git a/modules-available/exams/lang/en/template-tags.json b/modules-available/exams/lang/en/template-tags.json
index af87bb01..52173740 100644
--- a/modules-available/exams/lang/en/template-tags.json
+++ b/modules-available/exams/lang/en/template-tags.json
@@ -1,5 +1,4 @@
{
- "lang_actions": "Actions",
"lang_addExam": "Add exam period",
"lang_addingBasedOnLecture": "Adding exam period based on lecture",
"lang_allExamPeriods": "All Exam Periods",
@@ -16,7 +15,6 @@
"lang_deleteConfirmation": "Are you sure?",
"lang_description": "Description",
"lang_duration": "Duration",
- "lang_editExam": "Edit exam period",
"lang_end": "End",
"lang_end_date": "End Date",
"lang_end_time": "Time",
@@ -29,7 +27,7 @@
"lang_headingMain": "bwLehrpool Exam Mode",
"lang_id": "ID",
"lang_lectureName": "Lecture name",
- "lang_lectureOutOfRange": "Hint: Start or end date of given lecture lies outside of exam period given above",
+ "lang_lectureOutOfRange": "Hint: The exam period given above is shorter than the duration of the given lecture",
"lang_location": "Room\/Location",
"lang_locationInfo": "Select the rooms and locations you want to enable the exam mode in. Selecting nothing at all means that all clients will boot into exam mode during the given time period.",
"lang_locations": "Rooms\/Locations",
diff --git a/modules-available/exams/page.inc.php b/modules-available/exams/page.inc.php
index b32f758c..600089fc 100644
--- a/modules-available/exams/page.inc.php
+++ b/modules-available/exams/page.inc.php
@@ -10,9 +10,7 @@ class Page_Exams extends Page
private $rangeMin;
private $rangeMax;
private $userEditLocations = [];
- private $userDeleteLocations = [];
- private $userAddLocations = [];
- private $allowedLocations = [];
+ private $userViewLocations = [];
/** if examid is set, also add a column 'selected' **/
@@ -43,29 +41,37 @@ class Page_Exams extends Page
. "ORDER BY examid ASC");
while ($exam = $tmp->fetch(PDO::FETCH_ASSOC)) {
- // check if allowed to edit this exam
- if ($this->allowedToEdit($exam['examid'])) {
- $exam['allowedEdit'] = True;
+ $view = $edit = false;
+ // User has permission for all locations
+ if (in_array(0, $this->userViewLocations)) {
+ $view = true;
}
- // check if allowed to delete this exam
- if ($this->allowedToDelete($exam['examid'])) {
- $exam['allowedDelete'] = True;
+ if (in_array(0, $this->userEditLocations)) {
+ $edit = true;
}
-
-
- $locationids = explode(',', $exam['locationids']);
- // if global permission, add all exams to the list, no filter required
- if ($locationids[0] == 0) {
+ if ($view && $edit) {
$this->exams[] = $exam;
+ continue;
+ }
+ // Fine grained check by locations
+ if ($exam['locationids'] === null) {
+ $locationids = [0];
} else {
- foreach($locationids as $locid) {
- // only add the exam if permisson for atleast one of the exam locations
- if (in_array($locid, $this->allowedLocations)) {
- $this->exams[] = $exam;
- break;
- }
- }
+ $locationids = explode(',', $exam['locationids']);
+ }
+ if (!$view && empty(array_intersect($locationids, $this->userViewLocations))) {
+ // Not a single location in common, skip
+ continue;
}
+ if (!$edit && $this->userCanEditLocation($locationids)) {
+ // Only allow edit if user can edit all the locations the exam is assigned to
+ $edit = true;
+ }
+ // Set disabled string
+ if (!$edit) {
+ $exam['edit']['disabled'] = 'disabled';
+ }
+ $this->exams[] = $exam;
}
}
@@ -86,65 +92,34 @@ class Page_Exams extends Page
}
}
- // Returns the list of locations of the exam
- protected function getExamLocations($examid) {
- $res = Database::simpleQuery("SELECT locationid FROM exams_x_location WHERE examid= :examid", array('examid' => $examid));
- return $res;
- }
-
// Initialise the user-permission-based lists
- protected function setUserLocations() {
-
+ protected function setUserLocations()
+ {
// all locations the user has permission to edit
$this->userEditLocations = User::getAllowedLocations("exams.edit");
- // all locations the user has permission to delete
- $this->userDeleteLocations = User::getAllowedLocations("exams.delete");
- // all locations the user has permission to add
- $this->userAddLocations = User::getAllowedLocations("exams.add");
- // all locations the user has at least one of the 3 permissions
- $this->allowedLocations = array_unique(array_merge($this->userAddLocations, $this->userEditLocations, $this->userDeleteLocations));
- }
-
- // returns true if user is allowed to delete the exam
- protected function allowedToDelete($examid) {
-
- $res = $this->getExamLocations($examid);
- $locations = [];
- while ($locId = $res->fetch(PDO::FETCH_ASSOC)) {
- $locations[] = $locId['locationid'];
- }
-
- return empty(array_diff($locations, $this->userDeleteLocations));
-
- }
-
- // returns true if user is allowed to add an exam
- protected function allowedToAdd() {
- return User::hasPermission("exams.add");
+ $view = User::getAllowedLocations("exams.view");
+ // all locations the user can view or edit
+ $this->userViewLocations = array_unique(array_merge($this->userEditLocations, $view));
}
// returns true if user is allowed to edit the exam
- protected function allowedToEdit($examid) {
-
- $res = $this->getExamLocations($examid);
- $locations = [];
+ protected function userCanEditExam($examid = NULL)
+ {
+ if ($examid === null)
+ return User::hasPermission('exams.edit');
+ // Check locations of existing exam
+ $res = Database::simpleQuery("SELECT locationid FROM exams_x_location WHERE examid= :examid", array('examid' => $examid));
while ($locId = $res->fetch(PDO::FETCH_ASSOC)) {
- $locations[] = $locId['locationid'];
+ if (!in_array($locId['locationid'], $this->userEditLocations))
+ return false;
}
-
- return empty(array_diff($locations, $this->userEditLocations));
-
+ return true;
}
// checks if user is allowed to save an exam with all the locations
// needs information if it's add (second para = true) or edit (second para = false)
- protected function allowedToSave($locationids, $isAdd) {
-
- if ($isAdd) {
- return empty(array_diff($locationids, $this->userAddLocations));
- } else {
- return empty(array_diff($locationids, $this->userEditLocations));
- }
+ protected function userCanEditLocation($locationids) {
+ return empty(array_diff($locationids, $this->userEditLocations));
}
protected function makeItemsForVis()
@@ -225,7 +200,7 @@ class Page_Exams extends Page
$out = [];
foreach ($this->locations as $l) {
- if (in_array($l["locationid"], $this->allowedLocations)) {
+ if (in_array($l["locationid"], $this->userViewLocations)) {
$out[] = [
'id' => $l['locationid'],
'content' => $l['locationpad'] . ' ' . $l['locationname'],
@@ -315,6 +290,11 @@ class Page_Exams extends Page
$locationids[] = 0;
}
+ if (!$this->userCanEditLocation($locationids)) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=exams');
+ }
+
$examid = Request::post('examid', 0, 'int');
$starttime = strtotime(Request::post('starttime_date') . " " . Request::post('starttime_time'));
$endtime = strtotime(Request::post('endtime_date') . " " . Request::post('endtime_time'));
@@ -336,45 +316,41 @@ class Page_Exams extends Page
if ($examid === 0) {
// No examid given, is add
- if ($this->allowedToSave($locationids, True)) {
- $res = Database::exec("INSERT INTO exams(lectureid, starttime, endtime, autologin, description) VALUES(:lectureid, :starttime, :endtime, :autologin, :description);",
- compact('lectureid', 'starttime', 'endtime', 'autologin', 'description')) !== false;
+ $res = Database::exec("INSERT INTO exams(lectureid, starttime, endtime, autologin, description) VALUES(:lectureid, :starttime, :endtime, :autologin, :description);",
+ compact('lectureid', 'starttime', 'endtime', 'autologin', 'description')) !== false;
- $exam_id = Database::lastInsertId();
- foreach ($locationids as $lid) {
- $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:exam_id, :lid)", compact('exam_id', 'lid')) !== false;
- }
- if ($res === false) {
- Message::addError('exam-not-added');
- } else {
- Message::addInfo('exam-added-success');
- }
+ $exam_id = Database::lastInsertId();
+ foreach ($locationids as $lid) {
+ $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:exam_id, :lid)", compact('exam_id', 'lid')) !== false;
+ }
+ if ($res === false) {
+ Message::addError('exam-not-added');
+ } else {
+ Message::addInfo('exam-added-success');
}
Util::redirect('?do=exams');
}
// Edit
- if ($this->allowedToSave($locationids, False)) {
- $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid));
- if ($this->currentExam === false) {
- Message::addError('invalid-exam-id', $examid);
- Util::redirect('?do=exams');
- }
+ $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid));
+ if ($this->currentExam === false) {
+ Message::addError('invalid-exam-id', $examid);
+ Util::redirect('?do=exams');
+ }
- /* update fields */
- $res = Database::exec("UPDATE exams SET lectureid = :lectureid, starttime = :starttime, endtime = :endtime, autologin = :autologin, description = :description WHERE examid = :examid",
- compact('lectureid', 'starttime', 'endtime', 'description', 'examid', 'autologin')) !== false;
- /* drop all connections and reconnect to rooms */
- $res = $res && Database::exec("DELETE FROM exams_x_location WHERE examid = :examid", compact('examid')) !== false;
- /* reconnect */
- foreach ($locationids as $lid) {
- $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:examid, :lid)", compact('examid', 'lid')) !== false;
- }
- if ($res !== false) {
- Message::addInfo("changes-successfully-saved");
- } else {
- Message::addError("error-while-saving-changes");
- }
+ /* update fields */
+ $res = Database::exec("UPDATE exams SET lectureid = :lectureid, starttime = :starttime, endtime = :endtime, autologin = :autologin, description = :description WHERE examid = :examid",
+ compact('lectureid', 'starttime', 'endtime', 'description', 'examid', 'autologin')) !== false;
+ /* drop all connections and reconnect to rooms */
+ $res = $res && Database::exec("DELETE FROM exams_x_location WHERE examid = :examid", compact('examid')) !== false;
+ /* reconnect */
+ foreach ($locationids as $lid) {
+ $res = $res && Database::exec("INSERT INTO exams_x_location(examid, locationid) VALUES(:examid, :lid)", compact('examid', 'lid')) !== false;
+ }
+ if ($res !== false) {
+ Message::addInfo("changes-successfully-saved");
+ } else {
+ Message::addError("error-while-saving-changes");
}
Util::redirect('?do=exams');
}
@@ -408,28 +384,29 @@ class Page_Exams extends Page
$this->setUserLocations();
if ($this->action === 'show') {
+
$this->readExams();
$this->readLocations();
$this->readLectures();
} elseif ($this->action === 'add') {
- if($this->allowedToAdd()) {
- $this->readLectures();
- }
+ User::assertPermission('exams.edit');
+ $this->readLectures();
} elseif ($this->action === 'edit') {
- if($this->allowedToEdit($examid)) {
- $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid));
- if ($this->currentExam === false) {
- Message::addError('invalid-exam-id', $examid);
- Util::redirect('?do=exams');
- }
- $this->readLocations($examid);
- $this->readLectures();
-
+ if (!$this->userCanEditExam($examid)) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=exams');
}
+ $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid));
+ if ($this->currentExam === false) {
+ Message::addError('invalid-exam-id', $examid);
+ Util::redirect('?do=exams');
+ }
+ $this->readLocations($examid);
+ $this->readLectures();
} elseif ($this->action === 'save') {
@@ -441,7 +418,9 @@ class Page_Exams extends Page
die('delete only works with a post request');
}
- if ($this->allowedToDelete($examid)) {
+ if (!$this->userCanEditExam($examid)) {
+ Message::addError('main.no-permission');
+ } else {
$res1 = Database::exec("DELETE FROM exams WHERE examid = :examid;", compact('examid'));
$res2 = Database::exec("DELETE FROM exams_x_location WHERE examid = :examid;", compact('examid'));
if ($res1 === false || $res2 === false) {
@@ -462,23 +441,15 @@ class Page_Exams extends Page
protected function doRender()
{
- if (Request::isPost()) {
- $examid = Request::post('examid', 0, 'int');
- } else if (Request::isGet()) {
- $examid = Request::get('examid', 0, 'int');
- } else {
- die('Neither Post nor Get Request send.');
- }
-
if ($this->action === "show") {
+ User::assertPermission('exams.view');
// General title and description
Render::addTemplate('page-main-heading');
// List of defined exam periods
- Render::addTemplate('page-exams', [
- 'exams' => $this->makeExamsForTemplate(),
- 'allowedToAdd' => $this->allowedToAdd()
- ]);
+ $params = ['exams' => $this->makeExamsForTemplate()];
+ Permission::addGlobalTags($params['perms'], NULL, ['exams.edit']);
+ Render::addTemplate('page-exams', $params);
// List of upcoming lectures marked as exam
$upcoming = $this->makeLectureExamList();
if (empty($upcoming)) {
@@ -486,7 +457,7 @@ class Page_Exams extends Page
} else {
Render::addTemplate('page-upcoming-lectures', [
'pending_lectures' => $upcoming,
- 'allowedToAdd' => $this->allowedToAdd(),
+ 'allowedToAdd' => $this->userCanEditExam(),
'decollapse' => array_key_exists('class', end($upcoming))
]);
}
@@ -504,62 +475,59 @@ class Page_Exams extends Page
} elseif ($this->action === "add") {
- if($this->allowedToAdd()) {
- Render::setTitle(Dictionary::translate('title_add-exam'));
- $data = [];
- $baseLecture = Request::any('lectureid', false, 'string');
- $locations = null;
- if ($baseLecture !== false) {
- foreach ($this->lectures as &$lecture) {
- if ($lecture['lectureid'] === $baseLecture) {
- $data['exam'] = $this->makeEditFromArray($lecture);
- $locations = explode(',', $lecture['lids']);
- $lecture['selected'] = 'selected';
- break;
- }
+ Render::setTitle(Dictionary::translate('title_add-exam'));
+ $data = [];
+ $baseLecture = Request::any('lectureid', false, 'string');
+ $locations = null;
+ if ($baseLecture !== false) {
+ foreach ($this->lectures as &$lecture) {
+ if ($lecture['lectureid'] === $baseLecture) {
+ $data['exam'] = $this->makeEditFromArray($lecture);
+ $locations = explode(',', $lecture['lids']);
+ $lecture['selected'] = 'selected';
+ break;
}
- unset($lecture);
}
+ unset($lecture);
+ }
- $this->readLocations($locations);
- $data['lectures'] = $this->lectures;
- $data['locations'] = $this->locations;
+ $this->readLocations($locations);
+ $data['lectures'] = $this->lectures;
+ $data['locations'] = $this->locations;
- // if user has no permission to add for this location, disable the location in the select
- foreach ($data['locations'] as &$loc) {
- if (!in_array($loc["locationid"], $this->userAddLocations)) {
- $loc["disabled"] = "disabled";
- }
+ // if user has no permission to add for this location, disable the location in the select
+ foreach ($data['locations'] as &$loc) {
+ if (!in_array($loc["locationid"], $this->userEditLocations)) {
+ $loc["disabled"] = "disabled";
}
-
- Render::addTemplate('page-add-edit-exam', $data);
}
+ Render::addTemplate('page-add-edit-exam', $data);
+
} elseif ($this->action === 'edit') {
- if ($this->allowedToEdit($examid)) {
- Render::setTitle(Dictionary::translate('title_edit-exam'));
- $exam = $this->makeEditFromArray($this->currentExam);
- foreach ($this->lectures as &$lecture) {
- if ($lecture['lectureid'] === $this->currentExam['lectureid']) {
- $lecture['selected'] = 'selected';
- }
+ Render::setTitle(Dictionary::translate('title_edit-exam'));
+ $exam = $this->makeEditFromArray($this->currentExam);
+ foreach ($this->lectures as &$lecture) {
+ if ($lecture['lectureid'] === $this->currentExam['lectureid']) {
+ $lecture['selected'] = 'selected';
}
+ }
- $data = [];
- $data['exam'] = $exam;
- $data['locations'] = $this->locations;
- $data['lectures'] = $this->lectures;
+ $data = [];
+ $data['exam'] = $exam;
+ $data['locations'] = $this->locations;
+ $data['lectures'] = $this->lectures;
- // if user has no permission to edit for this location, disable the location in the select
- foreach ($data['locations'] as &$loc) {
- if (!in_array($loc["locationid"], $this->userEditLocations)) {
- $loc["disabled"] = "disabled";
- }
+ // if user has no permission to edit for this location, disable the location in the select
+ foreach ($data['locations'] as &$loc) {
+ if (!in_array($loc["locationid"], $this->userEditLocations)) {
+ $loc["disabled"] = "disabled";
}
-
- Render::addTemplate('page-add-edit-exam', $data);
}
+
+ Render::addTemplate('page-add-edit-exam', $data);
+
}
}
diff --git a/modules-available/exams/permissions/permissions.json b/modules-available/exams/permissions/permissions.json
index 215b3399..e44974b6 100644
--- a/modules-available/exams/permissions/permissions.json
+++ b/modules-available/exams/permissions/permissions.json
@@ -1,5 +1,8 @@
-[
- "exams.add",
- "exams.delete",
- "exams.edit"
-] \ No newline at end of file
+{
+ "exams.edit": {
+ "location-aware": true
+ },
+ "exams.view": {
+ "location-aware": true
+ }
+} \ No newline at end of file
diff --git a/modules-available/exams/templates/page-add-edit-exam.html b/modules-available/exams/templates/page-add-edit-exam.html
index 11bffed8..dc29a7f5 100644
--- a/modules-available/exams/templates/page-add-edit-exam.html
+++ b/modules-available/exams/templates/page-add-edit-exam.html
@@ -221,8 +221,8 @@ document.addEventListener("DOMContentLoaded", function () {
var to = e.data('to');
if (!from || !to)
return;
- from = slxMoment(from);
- to = slxMoment(to);
+ from = slxMoment.unix(from);
+ to = slxMoment.unix(to);
if (from.isBefore(sd) || to.isAfter(ed)) {
e.css('color', '#999');
e.data('inrange', false)
@@ -239,7 +239,7 @@ document.addEventListener("DOMContentLoaded", function () {
if (sel.val() === '' || sel.data('inrange')) {
$('#lecture-info').text('-');
} else {
- $('#lecture-info').text('{{lang_lectureOutOfRange}} (' + slxMoment(sel.data('from') * 1000).format('YYYY-MM-DD H:mm') + ' - ' + slxMoment(sel.data('to') * 1000).format('YYYY-MM-DD H:mm') + ')');
+ $('#lecture-info').text('{{lang_lectureOutOfRange}} (' + slxMoment.unix(sel.data('from')).format('YYYY-MM-DD H:mm') + ' - ' + slxMoment.unix(sel.data('to')).format('YYYY-MM-DD H:mm') + ')');
}
};
diff --git a/modules-available/exams/templates/page-exams.html b/modules-available/exams/templates/page-exams.html
index bb6cbd0a..df6a7dc9 100644
--- a/modules-available/exams/templates/page-exams.html
+++ b/modules-available/exams/templates/page-exams.html
@@ -5,7 +5,7 @@
</div>
<div class="panel-body">
<div class="slx-space">
- <table class="table table-bordered stupidtable">
+ <table class="table stupidtable">
<thead>
<tr>
<th data-sort="int">{{lang_id}}</th>
@@ -43,9 +43,9 @@
{{^liesInPast}}
<a onclick="slxShow({{starttime}}, {{endtime}})" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-eye-open"></span></a>
{{/liesInPast}}
- <a href="?do=exams&action=edit&examid={{examid}}" class="btn btn-default btn-sm {{^allowedEdit}}disabled{{/allowedEdit}}"><span class="glyphicon glyphicon-edit"></span></a> <input type="hidden" name="token" value="{{token}}">
+ <a href="?do=exams&action=edit&examid={{examid}}" class="btn btn-default btn-sm {{edit.disabled}}"><span class="glyphicon glyphicon-edit"></span></a> <input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="examid" value="{{examid}}">
- <button {{^allowedDelete}}disabled{{/allowedDelete}} class="btn {{btnClass}} btn-sm"><span class="glyphicon glyphicon-trash"></span></button>
+ <button {{edit.disabled}} class="btn {{btnClass}} btn-sm"><span class="glyphicon glyphicon-trash"></span></button>
</form>
</td>
</tr>
@@ -55,7 +55,7 @@
</div>
<div class="text-right">
<div class="btn-group" role="group">
- <a href="?do=exams&action=add" class="btn btn-success {{^allowedToAdd}}disabled{{/allowedToAdd}}"><span class="glyphicon glyphicon-plus-sign"></span> {{lang_addExam}}</a>
+ <a href="?do=exams&action=add" class="btn btn-success {{perms.exams.edit.disabled}}"><span class="glyphicon glyphicon-plus-sign"></span> {{lang_addExam}}</a>
</div>
</div>
</div>
diff --git a/modules-available/imgmanagement/config.json b/modules-available/imgmanagement/config.json
index 6454d96f..2fbb822f 100644
--- a/modules-available/imgmanagement/config.json
+++ b/modules-available/imgmanagement/config.json
@@ -1,4 +1,4 @@
{
- "category":"main.content",
- "permission":"1"
-}
+ "category": "main.content",
+ "permission": "1"
+} \ No newline at end of file
diff --git a/modules-available/internetaccess/config.json b/modules-available/internetaccess/config.json
index 706412d0..110f8b67 100644
--- a/modules-available/internetaccess/config.json
+++ b/modules-available/internetaccess/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.content"
-}
+ "category": "main.content"
+} \ No newline at end of file
diff --git a/modules-available/internetaccess/permissions/permissions.json b/modules-available/internetaccess/permissions/permissions.json
index 67998da7..09652e51 100644
--- a/modules-available/internetaccess/permissions/permissions.json
+++ b/modules-available/internetaccess/permissions/permissions.json
@@ -1,3 +1,5 @@
-[
- "configuration.safe"
-] \ No newline at end of file
+{
+ "configuration.safe": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/js_chart/config.json b/modules-available/js_chart/config.json
index de4d37b4..5adc886f 100644
--- a/modules-available/js_chart/config.json
+++ b/modules-available/js_chart/config.json
@@ -1,8 +1,6 @@
{
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
} \ No newline at end of file
diff --git a/modules-available/js_circles/config.json b/modules-available/js_circles/config.json
index de4d37b4..5adc886f 100644
--- a/modules-available/js_circles/config.json
+++ b/modules-available/js_circles/config.json
@@ -1,8 +1,6 @@
{
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
} \ No newline at end of file
diff --git a/modules-available/js_jqueryui/config.json b/modules-available/js_jqueryui/config.json
index 5a0c7960..69bb0aa9 100644
--- a/modules-available/js_jqueryui/config.json
+++ b/modules-available/js_jqueryui/config.json
@@ -1,9 +1,10 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/js_moment/config.json b/modules-available/js_moment/config.json
index 5a0c7960..96c02bce 100644
--- a/modules-available/js_moment/config.json
+++ b/modules-available/js_moment/config.json
@@ -1,9 +1,7 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/js_selectize/config.json b/modules-available/js_selectize/config.json
index 5a0c7960..69bb0aa9 100644
--- a/modules-available/js_selectize/config.json
+++ b/modules-available/js_selectize/config.json
@@ -1,9 +1,10 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/js_stupidtable/clientscript.js b/modules-available/js_stupidtable/clientscript.js
index 8b8fc107..0baa1546 100644
--- a/modules-available/js_stupidtable/clientscript.js
+++ b/modules-available/js_stupidtable/clientscript.js
@@ -1,9 +1,9 @@
/*
- Stupid jQuery table plugin.
+ Stupid jQuery table plugin. v1.1.3
https://github.com/joequery/Stupid-Table-Plugin
- Copyright (c) 2012 Joseph McCullough
+ Copyright (c) 2012-2017 Joseph McCullough
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -31,19 +31,77 @@
sortFns = sortFns || {};
sortFns = $.extend({}, $.fn.stupidtable.default_sort_fns, sortFns);
$table.data('sortFns', sortFns);
+ $table.stupidtable_build();
$table.on("click.stupidtable", "thead th", function() {
$(this).stupidsort();
});
- // to show the sort-arrow next to the table header
- $table.on("aftertablesort", function (event, data) {
- var th = $(this).find("th");
- th.find(".arrow").remove();
- var dir = $.fn.stupidtable.dir;
- var arrow = data.direction === dir.ASC ? "down" : "up";
- th.eq(data.column).append(' <span class="arrow glyphicon glyphicon-chevron-'+arrow+'"></span>');
+ // OpenSLX -- sort arrow; pointer cursor
+ var $sortThs = $table.find('th[data-sort]');
+ $sortThs.addClass('slx-pointer').append('<span class="glyphicon glyphicon-chevron-up sortarrow invisible"></span>');
+ var $arrows = $sortThs.find('.sortarrow');
+ var dir = $.fn.stupidtable.dir;
+ $table.on("aftertablesort", function (e, data) {
+ $arrows.addClass('invisible');
+ var addArrow = data.direction !== dir.ASC ? "down" : "up";
+ var remArrow = data.direction === dir.ASC ? "down" : "up";
+ console.log(data);
+ data.$th.find('.sortarrow').removeClass('invisible glyphicon-chevron-' + remArrow).addClass('glyphicon-chevron-' + addArrow);
});
+ // End OpenSLX
+
+ // Sort th immediately if data-sort-onload="yes" is specified. Limit to
+ // the first one found - only one default sort column makes sense anyway.
+ var $th_onload_sort = $table.find("th[data-sort-onload=yes]").eq(0);
+ $th_onload_sort.stupidsort();
+ });
+ };
+
+ // ------------------------------------------------------------------
+ // Default settings
+ // ------------------------------------------------------------------
+ $.fn.stupidtable.default_settings = {
+ should_redraw: function(sort_info){
+ return true;
+ },
+ will_manually_build_table: true // OpenSLX
+ };
+ $.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"};
+ $.fn.stupidtable.default_sort_fns = {
+ "int": function(a, b) {
+ return parseInt(a, 10) - parseInt(b, 10);
+ },
+ "float": function(a, b) {
+ return parseFloat(a) - parseFloat(b);
+ },
+ "string": function(a, b) {
+ return a.toString().localeCompare(b.toString());
+ },
+ "string-ins": function(a, b) {
+ a = a.toString().toLocaleLowerCase();
+ b = b.toString().toLocaleLowerCase();
+ return a.localeCompare(b);
+ },
+ // OpenSLX -- IPv4 sort function
+ "ipv4":function(a,b){
+ var aa = a.split(".");
+ var bb = b.split(".");
+
+ var resulta = aa[0]*0x1000000 + aa[1]*0x10000 + aa[2]*0x100 + aa[3]*1;
+ var resultb = bb[0]*0x1000000 + bb[1]*0x10000 + bb[2]*0x100 + bb[3]*1;
+
+ return resulta-resultb;
+ }
+ };
+
+ // Allow specification of settings on a per-table basis. Call on a table
+ // jquery object. Call *before* calling .stuidtable();
+ $.fn.stupidtable_settings = function(settings) {
+ return this.each(function() {
+ var $table = $(this);
+ var final_settings = $.extend({}, $.fn.stupidtable.default_settings, settings);
+ $table.stupidtable.settings = final_settings;
});
};
@@ -52,9 +110,6 @@
// Call on a table header.
$.fn.stupidsort = function(force_direction){
var $this_th = $(this);
- var th_index = 0; // we'll increment this soon
- var dir = $.fn.stupidtable.dir;
- var $table = $this_th.closest("table");
var datatype = $this_th.data("sort") || null;
// No datatype? Nothing to do.
@@ -62,91 +117,58 @@
return;
}
- // Account for colspans
- $this_th.parents("tr").find("th").slice(0, $(this).index()).each(function() {
- var cols = $(this).attr("colspan") || 1;
- th_index += parseInt(cols,10);
- });
+ var dir = $.fn.stupidtable.dir;
+ var $table = $this_th.closest("table");
- var sort_dir;
- if(arguments.length == 1){
- sort_dir = force_direction;
- }
- else{
- sort_dir = force_direction || $this_th.data("sort-default") || dir.ASC;
- if ($this_th.data("sort-dir"))
- sort_dir = $this_th.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC;
- }
+ var sort_info = {
+ $th: $this_th,
+ $table: $table,
+ datatype: datatype
+ };
- // Bail if already sorted in this direction
- if ($this_th.data("sort-dir") === sort_dir) {
- return;
+
+ // Bring in default settings if none provided
+ if(!$table.stupidtable.settings){
+ $table.stupidtable.settings = $.extend({}, $.fn.stupidtable.default_settings);
}
- // Go ahead and set sort-dir. If immediately subsequent calls have same sort-dir they will bail
- $this_th.data("sort-dir", sort_dir);
- $table.trigger("beforetablesort", {column: th_index, direction: sort_dir});
+ sort_info.compare_fn = $table.data('sortFns')[datatype];
+ sort_info.th_index = calculateTHIndex(sort_info);
+ sort_info.sort_dir = calculateSortDir(force_direction, sort_info);
+
+ $this_th.data("sort-dir", sort_info.sort_dir);
+ $table.trigger("beforetablesort", {column: sort_info.th_index, direction: sort_info.sort_dir, $th: $this_th});
// More reliable method of forcing a redraw
$table.css("display");
+ // OpenSLX -- decollapse table if we try to sort it
+ var $decol = $table.find('.slx-decollapse');
+ if ($decol.length > 0) {
+ $decol.click();
+ $decol.remove();
+ if ($table.stupidtable.settings.will_manually_build_table) $table.stupidtable_build();
+ }
+
// Run sorting asynchronously on a timout to force browser redraw after
// `beforetablesort` callback. Also avoids locking up the browser too much.
setTimeout(function() {
- // Gather the elements for this column
- var column = [];
- var sortFns = $table.data('sortFns');
- var sortMethod = sortFns[datatype];
- var collapsedCount = $table.children("tbody").children("tr.collapse").length;
- var trs = $table.children("tbody").children("tr:not(.slx-decollapse)");
-
- // Extract the data for the column that needs to be sorted and pair it up
- // with the TR itself into a tuple. This way sorting the values will
- // incidentally sort the trs.
- trs.each(function(index,tr) {
- var $e = $(tr).children().eq(th_index);
- var sort_val = $e.data("sort-value");
-
- // Store and read from the .data cache for display text only sorts
- // instead of looking through the DOM every time
- if(typeof(sort_val) === "undefined"){
- var txt = $e.text();
- $e.data('sort-value', txt);
- sort_val = txt;
- }
- column.push([sort_val, tr]);
- });
-
- // Sort by the data-order-by value
- column.sort(function(a, b) { return sortMethod(a[0], b[0]); });
- if (sort_dir != dir.ASC)
- column.reverse();
-
- // Replace the content of tbody with the sorted rows. Strangely
- // enough, .append accomplishes this for us.
- trs = $.map(column, function(kv) { return kv[1]; });
-
- if (collapsedCount > 0) {
- var showCount = trs.length - collapsedCount;
- for (var i = 0; i < trs.length; i++) {
- if (i < showCount) {
- $(trs[i]).removeClass("collapse");
- } else {
- $(trs[i]).addClass("collapse");
- }
- }
+ if(!$table.stupidtable.settings.will_manually_build_table){
+ $table.stupidtable_build();
}
+ var table_structure = sortTable(sort_info);
+ var trs = getTableRowsFromTableStructure(table_structure, sort_info);
- $table.children("tbody").prepend(trs);
-
- // Reset siblings
- $table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc");
- $this_th.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir);
+ if(!$table.stupidtable.settings.should_redraw(sort_info)){
+ return;
+ }
+ $table.children("tbody").append(trs);
- $table.trigger("aftertablesort", {column: th_index, direction: sort_dir});
+ updateElementData(sort_info);
+ $table.trigger("aftertablesort", {column: sort_info.th_index, direction: sort_info.sort_dir, $th: $this_th});
$table.css("display");
- }, 10);
+ }, 10);
return $this_th;
};
@@ -164,37 +186,157 @@
return $this_td;
};
- // ------------------------------------------------------------------
- // Default settings
- // ------------------------------------------------------------------
- $.fn.stupidtable.dir = {ASC: "asc", DESC: "desc"};
- $.fn.stupidtable.default_sort_fns = {
- "int": function(a, b) {
- return parseInt(a, 10) - parseInt(b, 10);
- },
- "float": function(a, b) {
- return parseFloat(a) - parseFloat(b);
- },
- "string": function(a, b) {
- return a.toString().localeCompare(b.toString());
- },
- "string-ins": function(a, b) {
- a = a.toString().toLocaleLowerCase();
- b = b.toString().toLocaleLowerCase();
- return a.localeCompare(b);
- },
- "ipv4":function(a,b){
- var aa = a.split(".");
- var bb = b.split(".");
- var resulta = aa[0]*0x1000000 + aa[1]*0x10000 + aa[2]*0x100 + aa[3]*1;
- var resultb = bb[0]*0x1000000 + bb[1]*0x10000 + bb[2]*0x100 + bb[3]*1;
+ $.fn.stupidtable_build = function(){
+ return this.each(function() {
+ var $table = $(this);
+ var table_structure = [];
+ var trs = $table.children("tbody").children("tr");
+ trs.each(function(index,tr) {
- return resulta-resultb;
+ // ====================================================================
+ // Transfer to using internal table structure
+ // ====================================================================
+ var ele = {
+ $tr: $(tr),
+ columns: [],
+ index: index
+ };
+
+ $(tr).children('td').each(function(idx, td){
+ var sort_val = $(td).data("sort-value");
+
+ // Store and read from the .data cache for display text only sorts
+ // instead of looking through the DOM every time
+ if(typeof(sort_val) === "undefined"){
+ var txt = $(td).text();
+ $(td).data('sort-value', txt);
+ sort_val = txt;
+ }
+ ele.columns.push(sort_val);
+ });
+ table_structure.push(ele);
+ });
+ $table.data('stupidsort_internaltable', table_structure);
+ });
+ };
+
+ // ====================================================================
+ // Private functions
+ // ====================================================================
+ var sortTable = function(sort_info){
+ var table_structure = sort_info.$table.data('stupidsort_internaltable');
+ var th_index = sort_info.th_index;
+ var $th = sort_info.$th;
+
+ var multicolumn_target_str = $th.data('sort-multicolumn');
+ var multicolumn_targets;
+ if(multicolumn_target_str){
+ multicolumn_targets = multicolumn_target_str.split(',');
+ }
+ else{
+ multicolumn_targets = [];
+ }
+ var multicolumn_th_targets = $.map(multicolumn_targets, function(identifier, i){
+ return get_th(sort_info.$table, identifier);
+ });
+
+ table_structure.sort(function(e1, e2){
+ var multicolumns = multicolumn_th_targets.slice(0); // shallow copy
+ var diff = sort_info.compare_fn(e1.columns[th_index], e2.columns[th_index]);
+ while(diff === 0 && multicolumns.length){
+ var multicolumn = multicolumns[0];
+ var datatype = multicolumn.$e.data("sort");
+ var multiCloumnSortMethod = sort_info.$table.data('sortFns')[datatype];
+ diff = multiCloumnSortMethod(e1.columns[multicolumn.index], e2.columns[multicolumn.index]);
+ multicolumns.shift();
+ }
+ // Sort by position in the table if values are the same. This enforces a
+ // stable sort across all browsers. See https://bugs.chromium.org/p/v8/issues/detail?id=90
+ if (diff === 0)
+ return e1.index - e2.index;
+ else
+ return diff;
+
+ });
+
+ if (sort_info.sort_dir != $.fn.stupidtable.dir.ASC){
+ table_structure.reverse();
+ }
+ return table_structure;
+ };
+
+ var get_th = function($table, identifier){
+ // identifier can be a th id or a th index number;
+ var $table_ths = $table.find('th');
+ var index = parseInt(identifier, 10);
+ var $th;
+ if(!index && index !== 0){
+ $th = $table_ths.siblings('#' + identifier);
+ index = $table_ths.index($th);
+ }
+ else{
+ $th = $table_ths.eq(index);
+ }
+ return {index: index, $e: $th};
+ };
+
+ var getTableRowsFromTableStructure = function(table_structure, sort_info){
+ // Gather individual column for callbacks
+ var column = $.map(table_structure, function(ele, i){
+ return [[ele.columns[sort_info.th_index], ele.$tr, i]];
+ });
+
+ /* Side effect */
+ sort_info.column = column;
+
+ // Replace the content of tbody with the sorted rows. Strangely
+ // enough, .append accomplishes this for us.
+ return $.map(table_structure, function(ele) { return ele.$tr; });
+
+ };
+
+ var updateElementData = function(sort_info){
+ var $table = sort_info.$table;
+ var $this_th = sort_info.$th;
+ var sort_dir = $this_th.data('sort-dir');
+ var th_index = sort_info.th_index;
+
+
+ // Reset siblings
+ $table.find("th").data("sort-dir", null).removeClass("sorting-desc sorting-asc");
+ $this_th.data("sort-dir", sort_dir).addClass("sorting-"+sort_dir);
+ };
+
+ var calculateSortDir = function(force_direction, sort_info){
+ var sort_dir;
+ var $this_th = sort_info.$th;
+ var dir = $.fn.stupidtable.dir;
+
+ if(!!force_direction){
+ sort_dir = force_direction;
+ }
+ else{
+ sort_dir = force_direction || $this_th.data("sort-default") || dir.ASC;
+ if ($this_th.data("sort-dir"))
+ sort_dir = $this_th.data("sort-dir") === dir.ASC ? dir.DESC : dir.ASC;
}
+ return sort_dir;
};
+
+ var calculateTHIndex = function(sort_info){
+ var th_index = 0;
+ var base_index = sort_info.$th.index();
+ sort_info.$th.parents("tr").find("th").slice(0, base_index).each(function() {
+ var cols = $(this).attr("colspan") || 1;
+ th_index += parseInt(cols,10);
+ });
+ return th_index;
+ };
+
})(jQuery);
+// OpenSLX -- apply to all elements with class stupidtable
document.addEventListener("DOMContentLoaded", function() {
var table = $(".stupidtable");
if (table.length) {
diff --git a/modules-available/js_stupidtable/config.json b/modules-available/js_stupidtable/config.json
index cf932d7e..5adc886f 100644
--- a/modules-available/js_stupidtable/config.json
+++ b/modules-available/js_stupidtable/config.json
@@ -1,8 +1,6 @@
{
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
} \ No newline at end of file
diff --git a/modules-available/js_stupidtable/style.css b/modules-available/js_stupidtable/style.css
deleted file mode 100644
index 614a3d38..00000000
--- a/modules-available/js_stupidtable/style.css
+++ /dev/null
@@ -1,3 +0,0 @@
-th[data-sort] {
- cursor: pointer;
-} \ No newline at end of file
diff --git a/modules-available/js_vis/config.json b/modules-available/js_vis/config.json
index 3b027d31..4c870a22 100644
--- a/modules-available/js_vis/config.json
+++ b/modules-available/js_vis/config.json
@@ -1,9 +1,12 @@
{
- "dependencies" : ["js_moment"],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [
+ "js_moment"
+ ],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/js_weekcalendar/clientscript.js b/modules-available/js_weekcalendar/clientscript.js
index 28b9e3cf..67637e65 100755
--- a/modules-available/js_weekcalendar/clientscript.js
+++ b/modules-available/js_weekcalendar/clientscript.js
@@ -132,7 +132,7 @@ function MyDate() {
eventHeader: function(calEvent, calendar) {
var options = calendar.weekCalendar('option');
var one_hour = 3600000;
- var displayTitleWithTime = calEvent.end.getTime() - calEvent.start.getTime() <= (one_hour / options.timeslotsPerHour);
+ var displayTitleWithTime = calEvent.end.getTime() - calEvent.start.getTime() < (one_hour / options.timeslotsPerHour);
if (displayTitleWithTime) {
return calendar.weekCalendar(
'formatTime', calEvent.start) +
diff --git a/modules-available/locationinfo/api.inc.php b/modules-available/locationinfo/api.inc.php
index ad71de8b..9ebbcea6 100644
--- a/modules-available/locationinfo/api.inc.php
+++ b/modules-available/locationinfo/api.inc.php
@@ -7,7 +7,7 @@
HandleParameters();
/**
- * Handles the API paramenters.
+ * Handles the API parameters.
*/
function HandleParameters()
{
@@ -20,7 +20,7 @@ function HandleParameters()
} elseif ($get === "machines") {
$locationIds = LocationInfo::getLocationsOr404($uuid);
$output = array();
- InfoPanel::appendMachineData($output, $locationIds, false);
+ InfoPanel::appendMachineData($output, $locationIds, true);
$output = array_values($output);
} elseif ($get === "config") {
$type = InfoPanel::getConfig($uuid, $output);
@@ -30,7 +30,7 @@ function HandleParameters()
}
} elseif ($get === "pcstates") {
$locationIds = LocationInfo::getLocationsOr404($uuid);
- $output = getPcStates($locationIds);
+ $output = getPcStates($locationIds, $uuid);
} elseif ($get === "locationtree") {
$locationIds = LocationInfo::getLocationsOr404($uuid);
$output = getLocationTree($locationIds);
@@ -84,7 +84,7 @@ function getLastChangeTs($paneluuid)
* @param int[] $idList list of the location ids.
* @return array aggregated PC states
*/
-function getPcStates($idList)
+function getPcStates($idList, $paneluuid)
{
$pcStates = array();
foreach ($idList as $id) {
@@ -99,13 +99,24 @@ function getPcStates($idList)
}
$locationInfoList = array();
- InfoPanel::appendMachineData($locationInfoList, $idList);
+ InfoPanel::appendMachineData($locationInfoList, $idList, true);
+
+ $panel = Database::queryFirst('SELECT paneluuid, panelconfig FROM locationinfo_panel WHERE paneluuid = :paneluuid',
+ compact('paneluuid'));
+ $config = json_decode($panel['panelconfig'], true);
+
foreach ($locationInfoList as $locationInfo) {
$id = $locationInfo['id'];
foreach ($locationInfo['machines'] as $pc) {
$key = strtolower($pc['pcState']);
if (isset($pcStates[$id][$key])) {
- $pcStates[$id][$key]++;
+ if ($config['roomplanner']) {
+ if (isset($pc['x']) && isset($pc['y'])) {
+ $pcStates[$id][$key]++;
+ }
+ } else {
+ $pcStates[$id][$key]++;
+ }
}
}
}
diff --git a/modules-available/locationinfo/config.json b/modules-available/locationinfo/config.json
index 87825809..837acfcf 100644
--- a/modules-available/locationinfo/config.json
+++ b/modules-available/locationinfo/config.json
@@ -1,4 +1,9 @@
{
- "category":"main.beta",
- "dependencies": ["js_jqueryui", "bootstrap_timepicker", "locations", "bootstrap_switch"]
-}
+ "category": "main.beta",
+ "dependencies": [
+ "js_jqueryui",
+ "bootstrap_timepicker",
+ "locations",
+ "bootstrap_switch"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/locationinfo/exchange-includes/README b/modules-available/locationinfo/exchange-includes/README
new file mode 100644
index 00000000..012de7df
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/README
@@ -0,0 +1,4 @@
+Copy of
+https://github.com/jamesiarmes/php-ews
+and its dependency php-ntlm, minus the
+composer stuff.
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType.php
new file mode 100644
index 00000000..ca202839
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType.
+ */
+
+namespace jamesiarmes\PhpEws;
+
+/**
+ * Base class for Exchange Web Service requests.
+ *
+ * @package php-ews\Array
+ */
+abstract class ArrayType extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppManifestsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppManifestsType.php
new file mode 100644
index 00000000..b1f105f6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppManifestsType.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfAppManifestsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a collection of base64-encoded app manifests that are installed for a
+ * email account.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfAppManifestsType extends ArrayType
+{
+ /**
+ * Contains the base64-encoded app manifest file.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string[]
+ *
+ * @todo Create a base64 class?
+ */
+ public $Manifest = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppsType.php
new file mode 100644
index 00000000..ba27c9be
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAppsType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfAppsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines information about all the XML manifest files for apps installed in a
+ * mailbox.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfAppsType extends ArrayType
+{
+ /**
+ * Contains information about an XML manifest file for a mail app that is
+ * installed in a mailbox.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\AppType[]
+ */
+ public $App = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfArraysOfTrackingPropertiesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfArraysOfTrackingPropertiesType.php
new file mode 100644
index 00000000..0491f1da
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfArraysOfTrackingPropertiesType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfArraysOfTrackingPropertiesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a property bag to store errors that are returned through the Web
+ * service.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfArraysOfTrackingPropertiesType extends ArrayType
+{
+ /**
+ * Contains a list of one or more tracking properties.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType[]
+ */
+ public $Properties = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttachmentsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttachmentsType.php
new file mode 100644
index 00000000..76bd0b59
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttachmentsType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfAttachmentsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Contains the items or files that are attached to an item in the Exchange
+ * store.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Figure out how to handle array classes.
+ */
+class ArrayOfAttachmentsType extends ArrayType
+{
+ /**
+ * Represents a file that is attached to an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FileAttachmentType[]
+ */
+ public $FileAttachment;
+
+ /**
+ * Represents an Exchange item that is attached to another Exchange item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemAttachmentType[]
+ */
+ public $ItemAttachment;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttendeeConflictData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttendeeConflictData.php
new file mode 100644
index 00000000..fc17e6ef
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfAttendeeConflictData.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfAttendeeConflictData.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of conflict data.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfAttendeeConflictData extends ArrayType
+{
+ /**
+ * Contains aggregate conflict information about the number of users
+ * available, the number of users who have conflicts, and the number of
+ * users who do not have availability information in a distribution list for
+ * a suggested meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\GroupAttendeeConflictData[]
+ */
+ public $GroupAttendeeConflictData = array();
+
+ /**
+ * Contains a user's or contact's free/busy status for a time window that
+ * occurs at the same time as the suggested meeting time identified in the
+ * Suggestion element.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IndividualAttendeeConflictData[]
+ */
+ public $IndividualAttendeeConflictData = array();
+
+ /**
+ * Represents an attendee that resolved as a distribution list that was too
+ * large to expand.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TooBigGroupAttendeeConflictData[]
+ */
+ public $TooBigGroupAttendeeConflictData = array();
+
+ /**
+ * Represents an unresolvable attendee or an attendee that is not a user,
+ * distribution list, or contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\UnknownAttendeeConflictData[]
+ */
+ public $UnknownAttendeeConflictData = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBaseItemIdsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBaseItemIdsType.php
new file mode 100644
index 00000000..e2a42014
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBaseItemIdsType.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfBaseItemIdsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines the unique identities of items, occurrence items, and recurring
+ * master items that are used to delete, send, get, move, or copy items in the
+ * Exchange store.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfBaseItemIdsType extends ArrayType
+{
+ /**
+ * Contains the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType[]
+ */
+ public $ItemId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBinaryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBinaryType.php
new file mode 100644
index 00000000..32cf354c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBinaryType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfBinaryType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a value that encodes a contact's certificate.
+ *
+ * @package php-ews\Type
+ */
+class ArrayOfBinaryType extends ArrayType
+{
+ /**
+ * Contains a Base64-encoded value.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $Base64Binary;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBodyContentAttributedValuesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBodyContentAttributedValuesType.php
new file mode 100644
index 00000000..c1980fc6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfBodyContentAttributedValuesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfBodyContentAttributedValuesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of BodyContentAttributedValue elements.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfBodyContentAttributedValuesType extends ArrayType
+{
+ /**
+ * Specifies the body content of an item.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\BodyContentAttributedValueType[]
+ */
+ public $BodyContentAttributedValue = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarEvent.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarEvent.php
new file mode 100644
index 00000000..e32a7cb6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarEvent.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfCalendarEvent.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a set of unique calendar item occurrences that represent the
+ * requested user's availability.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfCalendarEvent extends ArrayType
+{
+ /**
+ * Represents a unique calendar item occurrence.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarEvent[]
+ */
+ public $CalendarEvent = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarPermissionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarPermissionsType.php
new file mode 100644
index 00000000..32994050
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfCalendarPermissionsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfCalendarPermissionsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of calendar permissions for a folder.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfCalendarPermissionsType extends ArrayType
+{
+ /**
+ * Defines the access that a delegate user has to a calendar folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarPermissionType[]
+ */
+ public $CalendarPermission = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfContextProperty.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfContextProperty.php
new file mode 100644
index 00000000..ebafb93d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfContextProperty.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfContextProperty.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a set of context properties for an item.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfContextProperty extends ArrayType
+{
+ /**
+ * Specifies the context of an item.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContextPropertyType[]
+ */
+ public $ContextProperty = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationNodesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationNodesType.php
new file mode 100644
index 00000000..5c0149c9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationNodesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfConversationNodesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a collection of conversation nodes.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfConversationNodesType extends ArrayType
+{
+ /**
+ * Specifies a node in a conversation.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConversationNodeType
+ */
+ public $ConversationNode = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationsType.php
new file mode 100644
index 00000000..a21c7a23
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfConversationsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfConversationsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of conversations.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfConversationsType extends ArrayType
+{
+ /**
+ * Represents a single conversation.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConversationType[]
+ */
+ public $Conversation = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDLExpansionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDLExpansionType.php
new file mode 100644
index 00000000..ed6ee3ba
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDLExpansionType.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfDLExpansionType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of mailboxes that are contained in a distribution list.
+ *
+ * @package php-ews\Array
+ *
+ * @todo Implement FindResponsePagingAttributes trait.
+ */
+class ArrayOfDLExpansionType extends ArrayType
+{
+ /**
+ * Represents the next denominator to use for the next request when you are
+ * using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AbsoluteDenominator = array();
+
+ /**
+ * Indicates whether the current results contain the last item in the query
+ * so that additional paging is not needed.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludesLastItemInRange = array();
+
+ /**
+ * Represents the next index that should be used for the next request when
+ * you are using an indexed page view.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $IndexedPagingOffset = array();
+
+ /**
+ * Identifies a mail-enabled Active Directory directory service object.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType[]
+ */
+ public $Mailbox = array();
+
+ /**
+ * Represents the new numerator value to use for the next request when you
+ * are using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumeratorOffset = array();
+
+ /**
+ * Represents the total number of items in the view.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $TotalItemsInView = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserResponseMessageType.php
new file mode 100644
index 00000000..31cc534c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserResponseMessageType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfDelegateUserResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Contains the response messages for an Exchange Web Services delegate
+ * management request.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfDelegateUserResponseMessageType extends ArrayType
+{
+ /**
+ * Contains response messages for delegate management operations.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Response\DelegateUserResponseMessageType[]
+ */
+ public $DelegateUserResponseMessageType = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserType.php
new file mode 100644
index 00000000..94fc105a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDelegateUserType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfDelegateUserType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Contains the identities of delegates to add to or update in a mailbox.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfDelegateUserType extends ArrayType
+{
+ /**
+ * Identifies a single delegate to add to or update in a mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\DelegateUserType[]
+ */
+ public $DelegateUser = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDiscoverySearchConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDiscoverySearchConfigurationType.php
new file mode 100644
index 00000000..33e92963
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfDiscoverySearchConfigurationType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfDiscoverySearchConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of DiscoverySearchConfiguration elements.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfDiscoverySearchConfigurationType extends ArrayType
+{
+ /**
+ * Specifies the configuration for eDiscovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\DiscoverySearchConfigurationType[]
+ */
+ public $DiscoverySearchConfiguration = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressAttributedValuesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressAttributedValuesType.php
new file mode 100644
index 00000000..3a68d266
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressAttributedValuesType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressAttributedValuesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of EmailAddressAttributedValue values and the identifiers of
+ * their source attributions.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfEmailAddressAttributedValuesType extends ArrayType
+{
+ /**
+ * Specifies an instance of an array of email addresses and their associated
+ * attributions.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressAttributedValueType[]
+ */
+ public $EmailAddressAttributedValue = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressesType.php
new file mode 100644
index 00000000..4a6e1701
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEmailAddressesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Specifies an array of all email addresses of an associated persona.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfEmailAddressesType extends ArrayType
+{
+ /**
+ * Represents a fully resolved e-mail address.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType[]
+ */
+ public $Address = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEncryptedSharedFolderDataType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEncryptedSharedFolderDataType.php
new file mode 100644
index 00000000..bd86516d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfEncryptedSharedFolderDataType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfEncryptedSharedFolderDataType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of data structures that a client can use to authorize
+ * the sharing of its calendar or contact data with other clients.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfEncryptedSharedFolderDataType extends ArrayType
+{
+ /**
+ * Contains the encrypted data that a client can use to authorize the
+ * sharing of its calendar or contact data with other clients.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EncryptedSharedFolderDataType[]
+ */
+ public $EncryptedSharedFolderData = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedAttributesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedAttributesType.php
new file mode 100644
index 00000000..e9b6cc45
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedAttributesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfExtendedAttributesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Internal use only.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfExtendedAttributesType extends ArrayType
+{
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExtendedAttributeType[]
+ */
+ public $ExtendedAttribute = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedPropertyAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedPropertyAttributedValueType.php
new file mode 100644
index 00000000..77611cd3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfExtendedPropertyAttributedValueType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfExtendedPropertyAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines the extended properties used for a persona.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfExtendedPropertyAttributedValueType extends ArrayType
+{
+ /**
+ * Specifies extended properties for a persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExtendedPropertyAttributedValueType[]
+ */
+ public $ExtendedPropertyAttributedValue = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFailedSearchMailboxesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFailedSearchMailboxesType.php
new file mode 100644
index 00000000..3d13b635
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFailedSearchMailboxesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfFailedSearchMailboxesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of mailboxes that failed on search.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfFailedSearchMailboxesType extends ArrayType
+{
+ /**
+ * Specifies the error message for a mailbox that failed on search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\FailedSearchMailboxType[]
+ */
+ public $FailedMailbox = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFindMessageTrackingSearchResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFindMessageTrackingSearchResultType.php
new file mode 100644
index 00000000..19a0ab83
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFindMessageTrackingSearchResultType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfFindMessageTrackingSearchResultType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a list of records that match the search criteria.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfFindMessageTrackingSearchResultType extends ArrayType
+{
+ /**
+ * Contains a single message result for a FindMessageTrackingReportResponse
+ * element.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\FindMessageTrackingSearchResultType[]
+ */
+ public $MessageTrackingSearchResult = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFolderIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFolderIdType.php
new file mode 100644
index 00000000..c14019b0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFolderIdType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfFolderIdType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a list of folder identifiers.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfFolderIdType extends ArrayType
+{
+ /**
+ * Contains the identifier and change key of a folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType[]
+ */
+ public $FolderId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFoldersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFoldersType.php
new file mode 100644
index 00000000..340a89e3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFoldersType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfFoldersType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of folders that are used in folder operations.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfFoldersType extends ArrayType
+{
+ /**
+ * Represents a folder that primarily contains calendar items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarFolderType[]
+ */
+ public $CalendarFolder = array();
+
+ /**
+ * Represents a Contacts folder in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactsFolderType[]
+ */
+ public $ContactsFolder = array();
+
+ /**
+ * Identifies a folder to create, get, find, synchronize, or update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderType[]
+ */
+ public $Folder = array();
+
+ /**
+ * Represents a Search folder contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchFolderType[]
+ */
+ public $SearchFolder = array();
+
+ /**
+ * Represents a Tasks folder in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TasksFolderType[]
+ */
+ public $TasksFolder = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFreeBusyResponse.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFreeBusyResponse.php
new file mode 100644
index 00000000..4226b894
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfFreeBusyResponse.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfFreeBusyResponse.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents the requested users' availability information and the response
+ * status.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfFreeBusyResponse extends ArrayType
+{
+ /**
+ * Contains the free/busy information for a single mailbox user and the
+ * response status.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FreeBusyResponseType[]
+ */
+ public $FreeBusyResponse = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfGroupedItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfGroupedItemsType.php
new file mode 100644
index 00000000..dabdc358
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfGroupedItemsType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfGroupedItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of groups that are found with the search and
+ * aggregation criteria that is identified in the FindItem operation request.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfGroupedItemsType extends ArrayType
+{
+ /**
+ * Represents a collection of items that are the result of a grouped
+ * FindItem operation call.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\GroupedItemsType[]
+ */
+ public $GroupedItems = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfImGroupType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfImGroupType.php
new file mode 100644
index 00000000..1eed588c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfImGroupType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfImGroupType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of instant messaging (IM) groups.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfImGroupType extends ArrayType
+{
+ /**
+ * Represents an instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ImGroupType[]
+ */
+ public $ImGroup = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfInvalidRecipientsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfInvalidRecipientsType.php
new file mode 100644
index 00000000..0789a4df
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfInvalidRecipientsType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfInvalidRecipientsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents the recipients of a folder sharing request that are invalid.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfInvalidRecipientsType extends ArrayType
+{
+ /**
+ * Contains the SMTP address of the invalid recipient and information about
+ * why the recipient is invalid.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\InvalidRecipientType[]
+ */
+ public $InvalidRecipient = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfItemClassType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfItemClassType.php
new file mode 100644
index 00000000..41c8e267
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfItemClassType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfItemClassType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a list of item classes.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfItemClassType extends ArrayType
+{
+ /**
+ * Represents the message class of an item.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string[]
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ItemClassType[]
+ */
+ public $ItemClass = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfKeywordStatisticsSearchResultsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfKeywordStatisticsSearchResultsType.php
new file mode 100644
index 00000000..44efc1bb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfKeywordStatisticsSearchResultsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfKeywordStatisticsSearchResultsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a list of one or more KeywordStat elements.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfKeywordStatisticsSearchResultsType extends ArrayType
+{
+ /**
+ * Specifies keyword statistic information.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\KeywordStatisticsSearchResultType[]
+ */
+ public $KeywordStat = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailTipsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailTipsResponseMessageType.php
new file mode 100644
index 00000000..84842a49
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailTipsResponseMessageType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfMailTipsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a list of mail tips response messages.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfMailTipsResponseMessageType extends ArrayType
+{
+ /**
+ * Represents mail tips settings.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\MailTipsResponseMessageType[]
+ */
+ public $MailTipsResponseMessageType = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxData.php
new file mode 100644
index 00000000..81534153
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxData.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfMailboxData.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a list of mailboxes to query for availability information.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfMailboxData extends ArrayType
+{
+ /**
+ * Represents an individual mailbox user and options for the type of data to
+ * be returned about the mailbox user.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailboxData[]
+ */
+ public $MailboxData = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxHoldStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxHoldStatusType.php
new file mode 100644
index 00000000..bc6acff9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfMailboxHoldStatusType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfMailboxHoldStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a list of one or more mailbox hold statuses.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfMailboxHoldStatusType extends ArrayType
+{
+ /**
+ * Specifies the hold status of the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailboxHoldStatusType[]
+ */
+ public $MailboxHoldStatus = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemDetailsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemDetailsType.php
new file mode 100644
index 00000000..846b753b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemDetailsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfNonIndexableItemDetailsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of item details for non-indexable items.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfNonIndexableItemDetailsType extends ArrayType
+{
+ /**
+ * Specifies detail information about an item that cannot be indexed.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\NonIndexableItemDetailType[]
+ */
+ public $NonIndexableItemDetail = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemStatisticsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemStatisticsType.php
new file mode 100644
index 00000000..63164972
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfNonIndexableItemStatisticsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfNonIndexableItemStatisticsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of statistics for items that could not be indexed.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfNonIndexableItemStatisticsType extends ArrayType
+{
+ /**
+ * Contains a single statistic for an item that could not be indexed.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\NonIndexableItemStatisticType[]
+ */
+ public $NonIndexableItemStatistic = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfOccurrenceRangesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfOccurrenceRangesType.php
new file mode 100644
index 00000000..7b61e4e4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfOccurrenceRangesType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfOccurrenceRangesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of recurrence ranges.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfOccurrenceRangesType extends ArrayType
+{
+ /**
+ * Specifies a range of calendar item occurrences for a repeating calendar
+ * item.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\OccurrencesRangeType[]
+ */
+ public $Range = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleQuerySource.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleQuerySource.php
new file mode 100644
index 00000000..d6b954be
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleQuerySource.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfPeopleQuerySource.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines the source data for a persona query.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfPeopleQuerySource extends ArrayType
+{
+ /**
+ * Source data for the persona query.
+ *
+ * @since Exchange 2016
+ *
+ * @var string[]
+ */
+ public $Source = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleType.php
new file mode 100644
index 00000000..db68ba81
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPeopleType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfPeopleType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of persona data.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfPeopleType extends ArrayType
+{
+ /**
+ * Specifies a set of persona data.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaType[]
+ */
+ public $Persona = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPermissionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPermissionsType.php
new file mode 100644
index 00000000..d92db08b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPermissionsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfPermissionsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Contains the collection of permissions for a folder.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfPermissionsType extends ArrayType
+{
+ /**
+ * Defines the access that a delegate has to a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\PermissionType[]
+ */
+ public $Permission = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPersonaAttributionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPersonaAttributionsType.php
new file mode 100644
index 00000000..1b1f870b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPersonaAttributionsType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfPersonaAttributionsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Specifies an array of attribution information for one or more of the contacts
+ * or Active Directory recipients aggregated into the associated persona.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfPersonaAttributionsType extends ArrayType
+{
+ /**
+ * Specifies an instance in an array of attributes for a Persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaAttributionType[]
+ */
+ public $Attribution = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPhoneNumberAttributedValuesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPhoneNumberAttributedValuesType.php
new file mode 100644
index 00000000..1ebced35
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPhoneNumberAttributedValuesType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of phone numbers and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfPhoneNumberAttributedValuesType extends ArrayType
+{
+ /**
+ * Specifies an instance of an array of phone numbers and their associated
+ * attributions.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhoneNumberAttributedValueType[]
+ */
+ public $PhoneNumberAttributedValue = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPostalAddressAttributedValuesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPostalAddressAttributedValuesType.php
new file mode 100644
index 00000000..731ad9ca
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPostalAddressAttributedValuesType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfPostalAddressAttributedValuesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of business addresses and the identifiers of their source
+ * attributions.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfPostalAddressAttributedValuesType extends ArrayType
+{
+ /**
+ * Specifies an instance of an array of postal addresses and their
+ * associated attributions.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostalAddressAttributedValueType[]
+ */
+ public $PostalAddressAttributedValue = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPrivateCatalogAddInsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPrivateCatalogAddInsType.php
new file mode 100644
index 00000000..d31414cc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfPrivateCatalogAddInsType.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfPrivateCatalogAddInsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Undocumented.
+ *
+ * @package php-ews\Array
+ *
+ * @todo Update once documentation exists.
+ */
+class ArrayOfPrivateCatalogAddInsType extends ArrayType
+{
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\Type\PrivateCatalogAddInsType[]
+ *
+ * @todo Update once documentation exists.
+ */
+ public $AddIn = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfProtectionRulesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfProtectionRulesType.php
new file mode 100644
index 00000000..8d4e6123
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfProtectionRulesType.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfProtectionRulesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of protection rules.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfProtectionRulesType extends ArrayType
+{
+ /**
+ * Contains a single protection rule.
+ *
+ * This element can occur zero or more times. This element occurs zero times
+ * when no protection rules are defined by the organization. It occurs one
+ * or more times if at least one rule is defined by the organization.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleType[]
+ */
+ public $Rule = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRealItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRealItemsType.php
new file mode 100644
index 00000000..be59f020
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRealItemsType.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRealItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of items.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRealItemsType extends ArrayType
+{
+ /**
+ * Represents an Exchange calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarItemType[]
+ */
+ public $CalendarItem = array();
+
+ /**
+ * Represents an Exchange contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactItemType[]
+ */
+ public $Contact = array();
+
+ /**
+ * Represents a distribution list.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistributionListType[]
+ */
+ public $DistributionList = array();
+
+ /**
+ * Represents an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemType[]
+ */
+ public $Item = array();
+
+ /**
+ * Represents a meeting cancellation in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingCancellationMessageType[]
+ */
+ public $MeetingCancellation = array();
+
+ /**
+ * Represents a meeting message in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingMessageType[]
+ */
+ public $MeetingMessage = array();
+
+ /**
+ * Represents a meeting request in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingRequestMessageType[]
+ */
+ public $MeetingRequest = array();
+
+ /**
+ * Represents a meeting response in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingResponseMessageType[]
+ */
+ public $MeetingResponse = array();
+
+ /**
+ * Represents an Exchange e-mail message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MessageType[]
+ */
+ public $Message = array();
+
+ /**
+ * Represents a post item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostItemType[]
+ */
+ public $PostItem = array();
+
+ /**
+ * Represents a task in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TaskType[]
+ */
+ public $Task = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientTrackingEventType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientTrackingEventType.php
new file mode 100644
index 00000000..033e22e5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientTrackingEventType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientTrackingEventType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of one or more events for a message.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRecipientTrackingEventType extends ArrayType
+{
+ /**
+ * Contains details for a specific event in the tracking report.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecipientTrackingEventType[]
+ */
+ public $RecipientTrackingEvent = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientsType.php
new file mode 100644
index 00000000..56edcf92
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRecipientsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of recipients of an item.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRecipientsType extends ArrayType
+{
+ /**
+ * Identifies a mail-enabled Active Directory directory service object.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType[]
+ */
+ public $Mailbox = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRemindersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRemindersType.php
new file mode 100644
index 00000000..fd8ebf92
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRemindersType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRemindersType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents the reminders returned in the response to a GetReminders request.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRemindersType extends ArrayType
+{
+ /**
+ * Specifies a reminder for a task or a calendar item.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReminderType[]
+ */
+ public $Reminder = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResolutionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResolutionType.php
new file mode 100644
index 00000000..326caa90
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResolutionType.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfResolutionType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of resolutions for an ambiguous name.
+ *
+ * @package php-ews\Array
+ *
+ * @todo Implement FindResponsePagingAttributes trait.
+ */
+class ArrayOfResolutionType extends ArrayType
+{
+ /**
+ * Represents the next denominator to use for the next request when you are
+ * using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AbsoluteDenominator = array();
+
+ /**
+ * This attribute will be true if the current results contain the last item
+ * in the query, so that additional paging is not needed.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludesLastItemInRange = array();
+
+ /**
+ * Represents the next index that should be used for the next request when
+ * you are using an indexed page view.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $IndexedPagingOffset = array();
+
+ /**
+ * Represents the new numerator value to use for the next request when you
+ * are using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumeratorOffset = array();
+
+ /**
+ * Contains a single resolved entity.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ResolutionType[]
+ */
+ public $Resolution = array();
+
+ /**
+ * Represents the total number of items in the view.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $TotalItemsInView = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResponseMessagesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResponseMessagesType.php
new file mode 100644
index 00000000..7ca32e85
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfResponseMessagesType.php
@@ -0,0 +1,504 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfResponseMessagesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents the response messages for an Exchange Web Services request.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfResponseMessagesType extends ArrayType
+{
+ /**
+ * Contains the status and results of an ApplyConversationAction Operation
+ * request.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Response\ApplyConversationActionResponseMessageType[]
+ */
+ public $ApplyConversationActionResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single ArchiveItem request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\ItemInfoResponseMessageType[]
+ */
+ public $ArchiveItemResponseMessage = array();
+
+ /**
+ * Contains the status and result of a ConvertId request.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Response\ConvertIdResponseMessageType[]
+ */
+ public $ConvertIdResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single CopyFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FolderInfoResponseMessageType[]
+ */
+ public $CopyFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single CopyItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ItemInfoResponseMessageType[]
+ */
+ public $CopyItemResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single CreateAttachment request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\AttachmentInfoResponseMessageType[]
+ */
+ public $CreateAttachmentResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single CreateFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FolderInfoResponseMessageType[]
+ */
+ public $CreateFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single CreateItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ItemInfoResponseMessageType[]
+ */
+ public $CreateItemResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single CreateManagedFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FolderInfoResponseMessageType[]
+ */
+ public $CreateManagedFolderResponseMessage = array();
+
+ /**
+ * Contains the status and results of a CreateUserConfiguration request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $CreateUserConfigurationResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single DeleteAttachment request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\DeleteAttachmentResponseMessageType[]
+ */
+ public $DeleteAttachmentResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single DeleteFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $DeleteFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single DeleteItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $DeleteItemResponseMessage = array();
+
+ /**
+ * Contains the status and results of a DeleteUserConfiguration request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $DeleteUserConfigurationResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single EmptyFolder request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $EmptyFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single ExpandDL request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ExpandDLResponseMessageType[]
+ */
+ public $ExpandDLResponseMessage = array();
+
+ /**
+ * Contains the status and results of a single ExportItems request.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Response\ExportItemsResponseMessageType[]
+ */
+ public $ExportItemsResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single FindFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FindFolderResponseMessageType[]
+ */
+ public $FindFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single FindItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FindItemResponseMessageType[]
+ */
+ public $FindItemResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single FindMailboxStatisticsByKeyword
+ * request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\FindMailboxStatisticsByKeywordsResponseMessageType[]
+ */
+ public $FindMailboxStatisticsByKeywordsResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single GetAttachment request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\AttachmentInfoResponseMessageType[]
+ */
+ public $GetAttachmentResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single GetClientAccessToken request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetClientAccessTokenResponseMessageType[]
+ */
+ public $GetClientAccessTokenResponseMessage = array();
+
+ /**
+ * Specifies the response message for a GetConversationItems request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetConversationItemsResponseMessageType[]
+ */
+ public $GetConversationItemsResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single GetEvents request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetEventsResponseMessageType[]
+ */
+ public $GetEventsResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single GetFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FolderInfoResponseMessageType[]
+ */
+ public $GetFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single GetItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ItemInfoResponseMessageType[]
+ */
+ public $GetItemResponseMessage = array();
+
+ /**
+ * Contains the status and results of a GetReminders request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetRemindersResponseMessageType[]
+ */
+ public $GetRemindersResponse = array();
+
+ /**
+ * Contains the status and results of a GetRoomLists request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetRoomListsResponseMessageType[]
+ */
+ public $GetRoomListsResponse = array();
+
+ /**
+ * Contains the status and results of a GetRooms request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetRoomsResponseMessageType[]
+ */
+ public $GetRoomsResponse = array();
+
+ /**
+ * Contains the status and result of a single GetServerTimeZones request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetServerTimeZonesResponseMessageType[]
+ */
+ public $GetServerTimeZonesResponseMessage = array();
+
+ /**
+ * Contains the status and results of a GetSharingFolder request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetSharingFolderResponseMessageType[]
+ */
+ public $GetSharingFolderResponseMessage = array();
+
+ /**
+ * Contains the status and results of a GetSharingMetadata request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetSharingMetadataResponseMessageType[]
+ */
+ public $GetSharingMetadataResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single GetStreamingEvents request.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetStreamingEventsResponseMessageType[]
+ */
+ public $GetStreamingEventsResponseMessage = array();
+
+ /**
+ * Contains the status and results of a GetUserConfiguration request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetUserConfigurationResponseMessageType[]
+ */
+ public $GetUserConfigurationResponseMessage = array();
+
+ /**
+ * Contains the status and results of a GetUserPhoto request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\GetUserPhotoResponseMessageType[]
+ */
+ public $GetUserPhotoResponseMessage = array();
+
+ /**
+ * Defines a response message for a MarkAllItemsAsRead request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType
+ */
+ public $MarkAllItemsAsReadResponseMessage = array();
+
+ /**
+ * Defines a response message for a MarkAsJunk request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\MarkAsJunkResponseMessageType
+ */
+ public $MarkAsJunkResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single MoveFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FolderInfoResponseMessageType[]
+ */
+ public $MoveFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single MoveItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ItemInfoResponseMessageType[]
+ */
+ public $MoveItemResponseMessage = array();
+
+ /**
+ * Contains the status and results of a PerformReminderAction request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\PerformReminderActionResponseMessageType[]
+ */
+ public $PerformReminderActionResponse = array();
+
+ /**
+ * Contains the status and results of a RefreshSharingFolder request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\RefreshSharingFolderResponseMessageType[]
+ */
+ public $RefreshSharingFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a ResolveNames request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResolveNamesResponseMessageType[]
+ */
+ public $ResolveNamesResponseMessage = array();
+
+ /**
+ * Contains the status and result of a SearchMailboxes request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\SearchMailboxesResponseMessageType[]
+ */
+ public $SearchMailboxesResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single SendItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $SendItemResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single SendNotification request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\SendNotificationResponseMessageType[]
+ */
+ public $SendNotificationResponseMessage = array();
+
+ /**
+ * Contains the status and result of a SetHoldOnMailboxes request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Response\SetHoldOnMailboxesResponseMessageType[]
+ */
+ public $SetHoldOnMailboxesResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single Subscribe request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\SubscribeResponseMessageType[]
+ */
+ public $SubscribeResponseMessage = array();
+
+ /**
+ * Contains the status and result of a SyncFolderHierarchy request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\SyncFolderHierarchyResponseMessageType[]
+ */
+ public $SyncFolderHierarchyResponseMessage = array();
+
+ /**
+ * Contains the status and result of a SyncFolderItems request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\SyncFolderItemsResponseMessageType[]
+ */
+ public $SyncFolderItemsResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single Unsubscribe request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $UnsubscribeResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single UpdateFolder request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\FolderInfoResponseMessageType[]
+ */
+ public $UpdateFolderResponseMessage = array();
+
+ /**
+ * Contains the status and result of a single UpdateItem request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\UpdateItemResponseMessageType[]
+ */
+ public $UpdateItemResponseMessage = array();
+
+ /**
+ * Contains the status and results of an UpdateUserConfiguration request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType[]
+ */
+ public $UpdateUserConfigurationResponseMessage = array();
+
+ /**
+ * Contains the status and results of a single UploadItems request.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Response\UploadItemsResponseMessageType[]
+ */
+ public $UploadItemsResponseMessage = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRetentionPolicyTagsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRetentionPolicyTagsType.php
new file mode 100644
index 00000000..abd55f5c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRetentionPolicyTagsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRetentionPolicyTagsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a list of retention tags.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRetentionPolicyTagsType extends ArrayType
+{
+ /**
+ * Specifies the retention policy for a mailbox item.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\RetentionPolicyTagType[]
+ */
+ public $RetentionPolicyTag = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRoomsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRoomsType.php
new file mode 100644
index 00000000..963f1d65
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRoomsType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRoomsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents one or more meeting rooms.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRoomsType extends ArrayType
+{
+ /**
+ * Defines an e-mail address and display name that represents a meeting
+ * room.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RoomType[]
+ */
+ public $Room = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationErrorsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationErrorsType.php
new file mode 100644
index 00000000..48bad16f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationErrorsType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRuleOperationErrorsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of rule validation errors on each rule field that has an
+ * error.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRuleOperationErrorsType extends ArrayType
+{
+ /**
+ * Represents a rule operation error.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RuleOperationErrorType[]
+ */
+ public $RuleOperationError = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationsType.php
new file mode 100644
index 00000000..cb7ebd40
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleOperationsType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRuleOperationsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of rule operations that can be performed on an Inbox.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRuleOperationsType extends ArrayType
+{
+ /**
+ * Represents an operation to create a new Inbox rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\CreateRuleOperationType[]
+ */
+ public $CreateRuleOperation = array();
+
+ /**
+ * Represents an operation to delete an Inbox rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\DeleteRuleOperationType[]
+ */
+ public $DeleteRuleOperation = array();
+
+ /**
+ * Represents an operation to update an Inbox rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\SetRuleOperationType[]
+ */
+ public $SetRuleOperation = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleValidationErrorsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleValidationErrorsType.php
new file mode 100644
index 00000000..f5db0717
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRuleValidationErrorsType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRuleValidationErrorsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of rule validation errors on each rule field that has an
+ * error.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRuleValidationErrorsType extends ArrayType
+{
+ /**
+ * Represents a single validation error on a particular rule property value,
+ * predicate property value, or action property value.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RuleValidationErrorType[]
+ */
+ public $Error = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRulesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRulesType.php
new file mode 100644
index 00000000..850bfd80
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfRulesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfRulesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of rules in the user's mailbox.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfRulesType extends ArrayType
+{
+ /**
+ * Contains a single rule and represents a rule in the user's mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RuleType[]
+ */
+ public $Rule = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchItemKindsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchItemKindsType.php
new file mode 100644
index 00000000..355a783b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchItemKindsType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfSearchItemKindsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of messages to search.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfSearchItemKindsType extends ArrayType
+{
+ /**
+ * Indicates an item type to be searched.
+ *
+ * @since Exchange 2013
+ *
+ * @var string[]
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SearchItemKindType[]
+ */
+ public $SearchItemKind = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchPreviewItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchPreviewItemsType.php
new file mode 100644
index 00000000..03bdb61b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchPreviewItemsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfSearchPreviewItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a list of items available for preview.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfSearchPreviewItemsType extends ArrayType
+{
+ /**
+ * Specifies an item preview for a discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchPreviewItemType[]
+ */
+ public $SearchPreviewItem = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchableMailboxesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchableMailboxesType.php
new file mode 100644
index 00000000..974dbeea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSearchableMailboxesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfSearchableMailboxesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of mailboxes that can be searched.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfSearchableMailboxesType extends ArrayType
+{
+ /**
+ * Specifies a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchableMailboxType[]
+ */
+ public $SearchableMailbox = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationResponseMessageType.php
new file mode 100644
index 00000000..66a18d2f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationResponseMessageType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfServiceConfigurationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of service configuration response messages.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfServiceConfigurationResponseMessageType extends ArrayType
+{
+ /**
+ * Contains service configuration settings.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Response\ServiceConfigurationResponseMessageType[]
+ */
+ public $ServiceConfigurationResponseMessageType = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationType.php
new file mode 100644
index 00000000..76c0cf82
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfServiceConfigurationType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfServiceConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents service configurations.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfServiceConfigurationType extends ArrayType
+{
+ /**
+ * Specifies the requested service configurations by name.
+ *
+ * @since Exchange 2010
+ *
+ * @var string[]
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ServiceConfigurationType[]
+ */
+ public $ConfigurationName = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSmtpAddressType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSmtpAddressType.php
new file mode 100644
index 00000000..0ae49cf6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSmtpAddressType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfSmtpAddressType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of recipients of a message.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfSmtpAddressType extends ArrayType
+{
+ /**
+ * Represents the Simple Mail Transfer Protocol (SMTP) recipient address of
+ * a calendar or contact sharing request.
+ *
+ * @since Exchange 2010
+ *
+ * @var string[]
+ */
+ public $SmtpAddress = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringArrayAttributedValuesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringArrayAttributedValuesType.php
new file mode 100644
index 00000000..e3718171
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringArrayAttributedValuesType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfStringArrayAttributedValuesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Specifies an array of string data and identifiers of their source
+ * attributions.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfStringArrayAttributedValuesType extends ArrayType
+{
+ /**
+ * Specifies an instance of an array of string data.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\StringArrayAttributedValueType[]
+ */
+ public $StringArrayAttributedValue = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringAttributedValuesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringAttributedValuesType.php
new file mode 100644
index 00000000..09676b04
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringAttributedValuesType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of names and the identifiers of their source attributions
+ * for the associated persona.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfStringAttributedValuesType extends ArrayType
+{
+ /**
+ * Specifies an instance in an array of attributes associated with a persona
+ * element.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\StringAttributedValueType[]
+ */
+ public $StringAttributedValue = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php
new file mode 100644
index 00000000..6443d31d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of strings.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfStringsType extends ArrayType
+{
+ /**
+ * Contains a single string.
+ *
+ * @since Exchange 2007
+ *
+ * @var string[]
+ */
+ public $String = array();
+
+ /**
+ * Properly converts the value of this type to a string.
+ *
+ * @return string
+ *
+ * @todo Determine if this is needed.
+ */
+ public function __toString()
+ {
+ return $this->String;
+ }
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestion.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestion.php
new file mode 100644
index 00000000..44c7646f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestion.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfSuggestion.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of meeting suggestions.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfSuggestion extends ArrayType
+{
+ /**
+ * Represents a single meeting suggestion.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\Suggestion[]
+ */
+ public $Suggestion = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestionDayResult.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestionDayResult.php
new file mode 100644
index 00000000..c5b09ade
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfSuggestionDayResult.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfSuggestionDayResult.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of meeting suggestions organized by date.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfSuggestionDayResult extends ArrayType
+{
+ /**
+ * Represents a single day that contains suggested meeting times.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SuggestionDayResult[]
+ */
+ public $SuggestionDayResult = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTimeZoneDefinitionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTimeZoneDefinitionType.php
new file mode 100644
index 00000000..2fceb0ea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTimeZoneDefinitionType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfTimeZoneDefinitionType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of time zone definitions.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfTimeZoneDefinitionType extends ArrayType
+{
+ /**
+ * Specifies the periods and transitions that define a time zone.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType[]
+ */
+ public $TimeZoneDefinition = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTrackingPropertiesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTrackingPropertiesType.php
new file mode 100644
index 00000000..598690d2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTrackingPropertiesType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a list of one or more tracking properties.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfTrackingPropertiesType extends ArrayType
+{
+ /**
+ * Represents a name and value pair of strings that is used to create
+ * properties for message tracking reports.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\TrackingPropertyType[]
+ */
+ public $TrackingPropertyType = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsGroupsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsGroupsType.php
new file mode 100644
index 00000000..0b7c49e1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsGroupsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfTransitionsGroupsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of time zone transition groups.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfTransitionsGroupsType extends ArrayType
+{
+ /**
+ * Represents an array of time zone transitions.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTransitionsType[]
+ */
+ public $TransitionsGroup = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsType.php
new file mode 100644
index 00000000..4c0802e8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfTransitionsType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfTransitionsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of time zone transitions.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfTransitionsType extends ArrayType
+{
+ /**
+ * A time zone transition that occurs on a specific date and at a specific
+ * time.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\AbsoluteDateTransitionType[]
+ */
+ public $AbsoluteDateTransition = array();
+
+ /**
+ * The unique identifier of the transitions group.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Id = array();
+
+ /**
+ * A time zone transition that occurs on a specified day of the year.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurringDateTransitionType[]
+ */
+ public $RecurringDateTransition = array();
+
+ /**
+ * A time zone transition that occurs on the same day each year.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurringDayTransitionType[]
+ */
+ public $RecurringDayTransition = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUnknownEntriesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUnknownEntriesType.php
new file mode 100644
index 00000000..1f43f6b5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUnknownEntriesType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfUnknownEntriesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Contains an array of unknown permission entries that cannot be resolved
+ * against the Active Directory directory service.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfUnknownEntriesType extends ArrayType
+{
+ /**
+ * Represents a single unknown permission entry that cannot be resolved
+ * against Active Directory.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string[]
+ */
+ public $UnknownEntry = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserIdType.php
new file mode 100644
index 00000000..8394447d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserIdType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfUserIdType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of delegate users to get or remove from a principal's
+ * mailbox.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfUserIdType extends ArrayType
+{
+ /**
+ * Identifies a delegate to get or remove from a principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserIdType[]
+ */
+ public $UserId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserMailboxesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserMailboxesType.php
new file mode 100644
index 00000000..0c82725b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfUserMailboxesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfUserMailboxesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of mailboxes.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfUserMailboxesType extends ArrayType
+{
+ /**
+ * Identifies a single user's mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserMailboxType[]
+ */
+ public $UserMailbox = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfValueAttributionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfValueAttributionsType.php
new file mode 100644
index 00000000..fbd3759c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfValueAttributionsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfValueAttributionsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of attributions for an associated Value element.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfValueAttributionsType extends ArrayType
+{
+ /**
+ * Specifies a string used to identify an attribute.
+ *
+ * @since Exchange 2013
+ *
+ * @var string[]
+ */
+ public $Attribution = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfWorkingPeriod.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfWorkingPeriod.php
new file mode 100644
index 00000000..b2b0a518
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfWorkingPeriod.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\ArrayOfWorkingPeriod.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents working period information for the mailbox user.
+ *
+ * @package php-ews\Array
+ */
+class ArrayOfWorkingPeriod extends ArrayType
+{
+ /**
+ * Contains the work week days and hours of the mailbox user.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\WorkingPeriod[]
+ */
+ public $WorkingPeriod = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAllItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAllItemsType.php
new file mode 100644
index 00000000..1f13499b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAllItemsType.php
@@ -0,0 +1,217 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Identifies items of any type for numerous requests.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfAllItemsType extends ArrayType
+{
+ /**
+ * Represents an Accept reply to a meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AcceptItemType[]
+ */
+ public $AcceptItem = array();
+
+ /**
+ * Used to accept an invitation that allows access to another user’s
+ * calendar or contacts data.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\AcceptSharingInvitationType[]
+ */
+ public $AcceptSharingInvitation = array();
+
+ /**
+ * Represents an Exchange calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarItemType[]
+ */
+ public $CalendarItem = array();
+
+ /**
+ * Represents the response object that is used to cancel a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CancelCalendarItemType[]
+ */
+ public $CancelCalendarItem = array();
+
+ /**
+ * Represents an Exchange contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactItemType[]
+ */
+ public $Contact = array();
+
+ /**
+ * Represents a Decline reply to a meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DeclineItemType[]
+ */
+ public $DeclineItem = array();
+
+ /**
+ * Represents a distribution list.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistributionListType[]
+ */
+ public $DistributionList = array();
+
+ /**
+ * Contains an Exchange store item to forward to recipients.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ForwardItemType[]
+ */
+ public $ForwardItem = array();
+
+ /**
+ * Represents an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemType[]
+ */
+ public $Item = array();
+
+ /**
+ * Represents a meeting cancellation in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingCancellationMessageType[]
+ */
+ public $MeetingCancellation = array();
+
+ /**
+ * Represents a meeting message in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingMessageType[]
+ */
+ public $MeetingMessage = array();
+
+ /**
+ * Represents a meeting request in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingRequestMessageType[]
+ */
+ public $MeetingRequest = array();
+
+ /**
+ * Represents a meeting response in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingResponseMessageType[]
+ */
+ public $MeetingResponse = array();
+
+ /**
+ * Represents an Exchange e-mail message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MessageType[]
+ */
+ public $Message = array();
+
+ /**
+ * Contains a post item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostItemType[]
+ */
+ public $PostItem = array();
+
+ /**
+ * Contains a reply to a post item.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostReplyItemType[]
+ */
+ public $PostReplyItem = array();
+
+ /**
+ * Represents a response object that is used to remove a meeting item when a
+ * MeetingCancellation message is received.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RemoveItemType[]
+ */
+ public $RemoveItem = array();
+
+ /**
+ * Contains a reply to the sender and all identified recipients of an item
+ * in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReplyAllToItemType[]
+ */
+ public $ReplyAllToItem = array();
+
+ /**
+ * Contains a reply to the sender of an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReplyToItemType[]
+ */
+ public $ReplyToItem = array();
+
+ /**
+ * Used to suppress read receipts.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SuppressReadReceiptType[]
+ */
+ public $SuppressReadReceipt = array();
+
+ /**
+ * Represents a task in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TaskType[]
+ */
+ public $Task = array();
+
+ /**
+ * Represents a Tentative reply to a meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TentativelyAcceptItemType[]
+ */
+ public $TentativelyAcceptItem = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAlternateIdsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAlternateIdsType.php
new file mode 100644
index 00000000..369145f8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAlternateIdsType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAlternateIdsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines the source identifiers to convert.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfAlternateIdsType extends ArrayType
+{
+ /**
+ * Describes an item or folder identifier to convert.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\AlternateIdType[]
+ */
+ public $AlternateId = array();
+
+ /**
+ * Describes a public folder identifier to convert.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\AlternatePublicFolderIdType[]
+ */
+ public $AlternatePublicFolderId = array();
+
+ /**
+ * Describes a public folder item identifier to convert.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\AlternatePublicFolderItemIdType[]
+ */
+ public $AlternatePublicFolderItemId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfApplyConversationActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfApplyConversationActionType.php
new file mode 100644
index 00000000..5992e66f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfApplyConversationActionType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfApplyConversationActionType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a request to apply actions to items in a conversation.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfApplyConversationActionType extends ArrayType
+{
+ /**
+ * Contains a single action to be applied to a single conversation.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConversationActionType[]
+ */
+ public $ConversationAction = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttachmentsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttachmentsType.php
new file mode 100644
index 00000000..a5ca1c66
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttachmentsType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttachmentsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Contains the items or files that are attached to an item in the Exchange
+ * store.
+ *
+ * @package php-ews\Type
+ */
+class NonEmptyArrayOfAttachmentsType extends ArrayOfAttachmentsType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttendeesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttendeesType.php
new file mode 100644
index 00000000..de0f4abc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfAttendeesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttendeesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents attendees who are not required to attend a meeting.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfAttendeesType extends ArrayType
+{
+ /**
+ * Represents attendees and resources for a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AttendeeType[]
+ */
+ public $Attendee = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseFolderIdsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseFolderIdsType.php
new file mode 100644
index 00000000..e20b336c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseFolderIdsType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents the collection of folders that will be mined to determine the
+ * contents of a search folder.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfBaseFolderIdsType extends ArrayType
+{
+ /**
+ * Identifies MicrosoftExchange Server 2007 folders that can be referenced
+ * by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistinguishedFolderIdType[]
+ */
+ public $DistinguishedFolderId = array();
+
+ /**
+ * Contains the identifier and change key of a folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType[]
+ */
+ public $FolderId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseItemIdsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseItemIdsType.php
new file mode 100644
index 00000000..70a29c38
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfBaseItemIdsType.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents the unique identities of items, occurrence items, and recurring
+ * master items that are used to delete, send, get, move, or copy items in the
+ * Exchange store.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfBaseItemIdsType extends ArrayType
+{
+ /**
+ * Contains the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType[]
+ */
+ public $ItemId = array();
+
+ /**
+ * Identifies a single occurrence of a recurring item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\OccurrenceItemIdType[]
+ */
+ public $OccurrenceItemId = array();
+
+ /**
+ * Identifies a recurrence master item by identifying one of its related
+ * occurrence items' identifiers.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurringMasterItemIdType[]
+ */
+ public $RecurringMasterItemId = array();
+
+ /**
+ * Specifies an array of occurrence ranges.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurringMasterItemIdRanges[]
+ */
+ public $RecurringMasterItemIdRanges = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfClientAccessTokenRequestsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfClientAccessTokenRequestsType.php
new file mode 100644
index 00000000..79164a0c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfClientAccessTokenRequestsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfClientAccessTokenRequestsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of token requests.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfClientAccessTokenRequestsType extends ArrayType
+{
+ /**
+ * Specifies a single token request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ClientAccessTokenRequestType
+ */
+ public $TokenRequest = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfDeletedOccurrencesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfDeletedOccurrencesType.php
new file mode 100644
index 00000000..4aa80c09
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfDeletedOccurrencesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfDeletedOccurrencesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of deleted occurrences of a recurring calendar item.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfDeletedOccurrencesType extends ArrayType
+{
+ /**
+ * Represents a deleted occurrence of a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DeletedOccurrenceInfoType[]
+ */
+ public $DeletedOccurrence = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedFieldURIs.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedFieldURIs.php
new file mode 100644
index 00000000..c250edae
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedFieldURIs.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfExtendedFieldURIs.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines the extended properties used for a request.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfExtendedFieldURIs extends ArrayType
+{
+ /**
+ * Specifies an extended property for the Unified Contact Store.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType[]
+ */
+ public $ExtendedProperty = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedPropertyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedPropertyType.php
new file mode 100644
index 00000000..16639272
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfExtendedPropertyType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfExtendedPropertyType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * An array of additional properties.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfExtendedPropertyType extends ArrayType
+{
+ /**
+ * Identifies extended MAPI properties on folders and items.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExtendedPropertyType[]
+ */
+ public $ExtendedProperty = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFieldOrdersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFieldOrdersType.php
new file mode 100644
index 00000000..44aa4cbc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFieldOrdersType.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFieldOrdersType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines how items are sorted in a FindItem or FindConversation request.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfFieldOrdersType extends ArrayType
+{
+ /**
+ * Represents a single field by which to sort results and indicates the
+ * direction for the sort.
+ *
+ * One or more of these elements may be included.
+ *
+ * FieldOrder elements are applied in the order specified for sorting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FieldOrderType[]
+ */
+ public $FieldOrder = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangeDescriptionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangeDescriptionsType.php
new file mode 100644
index 00000000..0ef7d1e3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangeDescriptionsType.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFolderChangeDescriptionsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a set of elements that define append, set, and delete changes to
+ * folder properties.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfFolderChangeDescriptionsType extends ArrayType
+{
+ /**
+ * Represents data to append to a folder property during an UpdateFolder
+ * operation.
+ *
+ * This property is not implemented and should not be used.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AppendToFolderFieldType[]
+ */
+ public $AppendToFolderField = array();
+
+ /**
+ * Represents an operation to delete a given property from a folder during
+ * an UpdateFolder operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DeleteFolderFieldType[]
+ */
+ public $DeleteFolderField = array();
+
+ /**
+ * Represents an update to a single property on a folder in an UpdateFolder
+ * operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SetFolderFieldType[]
+ */
+ public $SetFolderField = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangesType.php
new file mode 100644
index 00000000..eff585c4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderChangesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFolderChangesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of changes for a folder.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfFolderChangesType extends ArrayType
+{
+ /**
+ * Represents a single change to be performed on a single folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderChangeType[]
+ */
+ public $FolderChange = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderNamesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderNamesType.php
new file mode 100644
index 00000000..03c7672d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFolderNamesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFolderNamesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of named managed folders to add to a mailbox.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfFolderNamesType extends ArrayType
+{
+ /**
+ * Identifies a single managed folder to add to mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string[]
+ */
+ public $FolderName = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFoldersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFoldersType.php
new file mode 100644
index 00000000..5a46a5f3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfFoldersType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFoldersType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of folders that are used in folder operations.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfFoldersType extends ArrayType
+{
+ /**
+ * Represents a folder that primarily contains calendar items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarFolderType[]
+ */
+ public $CalendarFolder = array();
+
+ /**
+ * Represents a Contacts folder in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactsFolderType[]
+ */
+ public $ContactsFolder = array();
+
+ /**
+ * Identifies a folder to create, get, find, synchronize, or update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderType[]
+ */
+ public $Folder = array();
+
+ /**
+ * Represents a Search folder contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchFolderType[]
+ */
+ public $SearchFolder = array();
+
+ /**
+ * Represents a Tasks folder in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TasksFolderType[]
+ */
+ public $TasksFolder = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfGroupIdentifiersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfGroupIdentifiersType.php
new file mode 100644
index 00000000..48e52c09
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfGroupIdentifiersType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfGroupIdentifiersType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of Active Directory directory service group object
+ * security identifiers.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfGroupIdentifiersType extends ArrayType
+{
+ /**
+ * Represents a single security identifier and attribute for an Active
+ * Directory object group of which the account is a member.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SidAndAttributesType[]
+ */
+ public $GroupIdentifier = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfInternetHeadersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfInternetHeadersType.php
new file mode 100644
index 00000000..ee45cbc2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfInternetHeadersType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfInternetHeadersType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of some of the Internet message headers that are
+ * contained in an item in a mailbox.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfInternetHeadersType extends ArrayType
+{
+ /**
+ * Represents the Internet message header for a given header within the
+ * headers collection.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\InternetHeaderType[]
+ */
+ public $InternetMessageHeader = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangeDescriptionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangeDescriptionsType.php
new file mode 100644
index 00000000..6793af26
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangeDescriptionsType.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemChangeDescriptionsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a set of elements that define append, set, and delete changes to
+ * item properties.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfItemChangeDescriptionsType extends ArrayType
+{
+ /**
+ * Represents data to append to a single property of an item during an
+ * UpdateItem operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AppendToItemFieldType[]
+ */
+ public $AppendToItemField = array();
+
+ /**
+ * Represents an operation to delete a given property from an item during an
+ * UpdateItem operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DeleteItemFieldType[]
+ */
+ public $DeleteItemField = array();
+
+ /**
+ * Represents an update to a single property of an item in an UpdateItem
+ * operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SetItemFieldType[]
+ */
+ public $SetItemField = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangesType.php
new file mode 100644
index 00000000..7def9f1c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemChangesType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemChangesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of ItemChange elements that identify items and the
+ * updates to apply to the items.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfItemChangesType extends ArrayType
+{
+ /**
+ * Contains an item identifier and the updates to apply to the item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemChangeType[]
+ */
+ public $ItemChange = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemIdsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemIdsType.php
new file mode 100644
index 00000000..7073a1f4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfItemIdsType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemIdsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of item ids.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfItemIdsType extends ArrayType
+{
+ /**
+ * Specifies the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType[]
+ */
+ public $ItemId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxQueriesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxQueriesType.php
new file mode 100644
index 00000000..09723310
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxQueriesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfMailboxQueriesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a list of mailboxes and associated queries for discovery search.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfMailboxQueriesType extends ArrayType
+{
+ /**
+ * Specifies a query and the scope of a discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailboxQueryType[]
+ */
+ public $MailboxQuery = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxSearchScopesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxSearchScopesType.php
new file mode 100644
index 00000000..f6a53bb1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfMailboxSearchScopesType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfMailboxSearchScopesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines a list of one or more mailboxes and associated search scopes for a
+ * discovery search.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfMailboxSearchScopesType extends ArrayType
+{
+ /**
+ * Specifies a mailbox and a search scope for a discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailboxSearchScopeType[]
+ */
+ public $MailboxSearchScope = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationEventTypesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationEventTypesType.php
new file mode 100644
index 00000000..3ae4182b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationEventTypesType.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfNotificationEventTypesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of event notification types that are used to create a
+ * subscription.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfNotificationEventTypesType extends ArrayType
+{
+ /**
+ * Represents a requested event notification type that is used to create a
+ * subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string[]
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\NotificationEventTypeType[]
+ */
+ public $EventType = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationsType.php
new file mode 100644
index 00000000..6461aba8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfNotificationsType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfNotificationsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of information about the subscription and the events that
+ * have occurred since the last notification.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfNotificationsType extends ArrayType
+{
+ /**
+ * Contains information about the subscription and the events that have
+ * occurred since the last notification.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\NotificationType[]
+ */
+ public $Notification = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfOccurrenceInfoType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfOccurrenceInfoType.php
new file mode 100644
index 00000000..8368750d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfOccurrenceInfoType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfOccurrenceInfoType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of recurring calendar item occurrences that have been
+ * modified so that they are different than the recurrence master item.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfOccurrenceInfoType extends ArrayType
+{
+ /**
+ * Represents a single modified occurrence of a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\OccurrenceInfoType[]
+ */
+ public $Occurrence = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPathsToElementType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPathsToElementType.php
new file mode 100644
index 00000000..e27760de
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPathsToElementType.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines additional properties for use in GetItem, UpdateItem, CreateItem,
+ * FindItem, or FindFolder requests.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfPathsToElementType extends ArrayType
+{
+ /**
+ * Identifies extended MAPI properties to get, set, or create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType[]
+ */
+ public $ExtendedFieldURI = array();
+
+ /**
+ * Identifies frequently referenced properties by URI.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToUnindexedFieldType[]
+ */
+ public $FieldURI = array();
+
+ /**
+ * Identifies frequently referenced dictionary properties by URI.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToIndexedFieldType[]
+ */
+ public $IndexedFieldURI = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPeriodsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPeriodsType.php
new file mode 100644
index 00000000..ae1e8a97
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPeriodsType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPeriodsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of periods that define the time offset at different
+ * stages of a time zone.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfPeriodsType extends ArrayType
+{
+ /**
+ * The name, time offset, and unique identifier for a specific stage of a
+ * time zone.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\PeriodType[]
+ */
+ public $Period = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPropertyValuesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPropertyValuesType.php
new file mode 100644
index 00000000..8d5e7284
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfPropertyValuesType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPropertyValuesType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of values for an extended property.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfPropertyValuesType extends ArrayType
+{
+ /**
+ * Contains a value of an extended property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string[]
+ */
+ public $Value = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfReminderItemActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfReminderItemActionType.php
new file mode 100644
index 00000000..c4803c82
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfReminderItemActionType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfReminderItemActionType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines the actions for reminder items.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfReminderItemActionType extends ArrayType
+{
+ /**
+ * Specifies the action for a reminder item.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReminderItemActionType
+ */
+ public $ReminderItemAction = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRequestAttachmentIdsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRequestAttachmentIdsType.php
new file mode 100644
index 00000000..3a89c9fc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRequestAttachmentIdsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfRequestAttachmentIdsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of attachment identifiers.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfRequestAttachmentIdsType extends ArrayType
+{
+ /**
+ * The element that identifies a single attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RequestAttachmentIdType[]
+ */
+ public $AttachmentId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfResponseObjectsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfResponseObjectsType.php
new file mode 100644
index 00000000..e047392e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfResponseObjectsType.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfResponseObjectsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of all the response objects that are associated with
+ * an item in the Exchange store.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfResponseObjectsType extends ArrayType
+{
+ /**
+ * Represents an Accept reply to a meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AcceptItemType[]
+ */
+ public $AcceptItem = array();
+
+ /**
+ * Used to accept an invitation that allows access to another user’s
+ * calendar or contacts data.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\AcceptSharingInvitationType[]
+ */
+ public $AcceptSharingInvitation = array();
+
+ /**
+ * Represents the response object used to cancel a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarItemType[]
+ */
+ public $CancelCalendarItem = array();
+
+ /**
+ * Represents a Decline reply to a meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DeclineItemType[]
+ */
+ public $DeclineItem = array();
+
+ /**
+ * Contains an Exchange store item to forward to recipients.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ForwardItemType[]
+ */
+ public $ForwardItem = array();
+
+ /**
+ * Contains a reply to a post item.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostReplyItemType[]
+ */
+ public $PostReplyItem = array();
+
+ /**
+ * Specifies a response object that indicates that the meeting attendee can
+ * propose a new meeting time.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProposeNewTimeType[]
+ */
+ public $ProposeNewTime = array();
+
+ /**
+ * Removes an item from the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RemoveItemType[]
+ */
+ public $RemoveItem = array();
+
+ /**
+ * Contains a reply to all identified recipients of an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReplyAllToItemType[]
+ */
+ public $ReplyAllToItem = array();
+
+ /**
+ * Contains a reply to the creator of an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReplyToItemType[]
+ */
+ public $ReplyToItem = array();
+
+ /**
+ * Used to suppress read receipt requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SuppressReadReceiptType[]
+ */
+ public $SuppressReadReceipt = array();
+
+ /**
+ * Represents a Tentative reply to a meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TentativelyAcceptItemType[]
+ */
+ public $TentativelyAcceptItem = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRestrictedGroupIdentifiersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRestrictedGroupIdentifiersType.php
new file mode 100644
index 00000000..7d819c96
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfRestrictedGroupIdentifiersType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfRestrictedGroupIdentifiersType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents a collection of restricted groups from a user's token.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfRestrictedGroupIdentifiersType extends ArrayType
+{
+ /**
+ * Represents the group security identifier (SID) and attributes for a
+ * restricted group.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SidAndAttributesType[]
+ */
+ public $RestrictedGroupIdentifier = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfSubscriptionIdsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfSubscriptionIdsType.php
new file mode 100644
index 00000000..2e3db551
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfSubscriptionIdsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfSubscriptionIdsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of invalid subscription IDs.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfSubscriptionIdsType extends ArrayType
+{
+ /**
+ * Represents the identifier for a subscription.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string[]
+ */
+ public $SubscriptionId = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfTimeZoneIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfTimeZoneIdType.php
new file mode 100644
index 00000000..fb8ec2ec
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfTimeZoneIdType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfTimeZoneIdType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of time zone definition identifiers.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfTimeZoneIdType extends ArrayType
+{
+ /**
+ * The element that identifies a single time zone definition.
+ *
+ * @since Exchange 2010
+ *
+ * @var string[]
+ */
+ public $Id = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfUploadItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfUploadItemsType.php
new file mode 100644
index 00000000..d1978f3d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayOfUploadItemsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfUploadItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Represents an array of items to upload into a mailbox.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayOfUploadItemsType extends ArrayType
+{
+ /**
+ * Represents a single item to upload into a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\UploadItemType[]
+ */
+ public $Item = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayofLegacyDNsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayofLegacyDNsType.php
new file mode 100644
index 00000000..34833cea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/NonEmptyArrayofLegacyDNsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayofLegacyDNsType.
+ */
+
+namespace jamesiarmes\PhpEws\ArrayType;
+
+use \jamesiarmes\PhpEws\ArrayType;
+
+/**
+ * Defines an array of mailboxes identified by legacy distinguished name.
+ *
+ * @package php-ews\Array
+ */
+class NonEmptyArrayofLegacyDNsType extends ArrayType
+{
+ /**
+ * Identifies a mailbox by its legacy distinguished name.
+ *
+ * @since Exchange 2013
+ *
+ * @var string[]
+ */
+ public $LegacyDN = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Autodiscover.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Autodiscover.php
new file mode 100644
index 00000000..8198137d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Autodiscover.php
@@ -0,0 +1,896 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Autodiscover.
+ */
+
+namespace jamesiarmes\PhpEws;
+
+/**
+ * Exchange Web Services Autodiscover implementation
+ *
+ * This class supports POX (Plain Old XML), which is deprecated but functional
+ * in Exchange 2010. It may make sense for you to combine your Autodiscovery
+ * efforts with a SOAP Autodiscover request as well.
+ *
+ * USAGE:
+ *
+ * (after any auto-loading class incantation)
+ *
+ * $ews = EWSAutodiscover::getEWS($email, $password);
+ *
+ * -- OR --
+ *
+ * If there are issues with your cURL installation that require you to specify
+ * a path to a valid Certificate Authority, you can configure that manually.
+ *
+ * $auto = new EWSAutodiscover($email, $password);
+ * $auto->setCAInfo('/path/to/your/cacert.pem');
+ * $ews = $auto->newEWS();
+ *
+ * @link http://technet.microsoft.com/en-us/library/bb332063(EXCHG.80).aspx
+ * @link https://www.testexchangeconnectivity.com/
+ *
+ * @package php-ews\AutoDiscovery
+ */
+class Autodiscover
+{
+ /**
+ * The path appended to the various schemes and hostnames used during
+ * autodiscovery.
+ *
+ * @var string
+ */
+ const AUTODISCOVER_PATH = '/autodiscover/autodiscover.xml';
+
+ /**
+ * Server was discovered using the TLD method.
+ *
+ * @var integer
+ */
+ const AUTODISCOVERED_VIA_TLD = 10;
+
+ /**
+ * Server was discovered using the subdomain method.
+ *
+ * @var integer
+ */
+ const AUTODISCOVERED_VIA_SUBDOMAIN = 11;
+
+ /**
+ * Server was discovered using the unauthenticated GET method.
+ *
+ * @var integer
+ */
+ const AUTODISCOVERED_VIA_UNAUTHENTICATED_GET = 12;
+
+ /**
+ * Server was discovered using the DNS SRV redirect method.
+ *
+ * @var integer
+ */
+ const AUTODISCOVERED_VIA_SRV_RECORD = 13;
+
+ /**
+ * Server was discovered using the HTTP redirect method.
+ *
+ * @var integer
+ *
+ * @todo We do not currently support this.
+ */
+ const AUTODISCOVERED_VIA_RESPONSE_REDIRECT = 14;
+
+ /**
+ * The email address to attempt autodiscovery against.
+ *
+ * @var string
+ */
+ protected $email;
+
+ /**
+ * The password to present during autodiscovery.
+ *
+ * @var string
+ */
+ protected $password;
+
+ /**
+ * The Exchange username to use during authentication. If unspecified,
+ * the provided email address will be used as the username.
+ *
+ * @var string
+ */
+ protected $username;
+
+ /**
+ * The top-level domain name, extracted from the provided email address.
+ *
+ * @var string
+ */
+ protected $tld;
+
+ /**
+ * The Autodiscover XML request. Since it's used repeatedly, it's cached
+ * in this property to avoid redundant re-generation.
+ *
+ * @var string
+ */
+ protected $requestxml;
+
+ /**
+ * The Certificate Authority path. Should point to a directory containing
+ * one or more certificates to use in SSL verification.
+ *
+ * @var string
+ */
+ protected $capath;
+
+ /**
+ * The path to a specific Certificate Authority file. Get one and use it
+ * for full Autodiscovery compliance.
+ *
+ * @var string
+ *
+ * @link http://curl.haxx.se/ca/cacert.pem
+ * @link http://curl.haxx.se/ca/
+ */
+ protected $cainfo;
+
+ /**
+ * Skip SSL verification. Bad idea, and violates the strict Autodiscover
+ * protocol. But, here in case you have no other option.
+ * Defaults to FALSE.
+ *
+ * @var boolean
+ */
+ protected $skip_ssl_verification = false;
+
+ /**
+ * The body of the last response.
+ *
+ * @var string
+ */
+ public $last_response;
+
+ /**
+ * An associative array of response headers that resulted from the
+ * last request. Keys are lowercased for easy checking.
+ *
+ * @var array
+ */
+ public $last_response_headers;
+
+ /**
+ * The output of curl_info() relating to the most recent cURL request.
+ *
+ * @var array
+ */
+ public $last_info;
+
+ /**
+ * The cURL error code associated with the most recent cURL request.
+ *
+ * @var integer
+ */
+ public $last_curl_errno;
+
+ /**
+ * Human-readable description of the most recent cURL error.
+ *
+ * @var string
+ */
+ public $last_curl_error;
+
+ /**
+ * The value in seconds to use for Autodiscover host connection timeouts.
+ * Default connection timeout is 2 seconds, so that unresponsive methods
+ * can be bypassed quickly.
+ *
+ * @var integer
+ */
+ public $connection_timeout = 2;
+
+ /**
+ * Information about an Autodiscover Response containing an error will
+ * be stored here.
+ *
+ * @var mixed
+ */
+ public $error = false;
+
+ /**
+ * Information about an Autodiscover Response with a redirect will be
+ * retained here.
+ *
+ * @var mixed
+ */
+ public $redirect = false;
+
+ /**
+ * A successful, non-error and non-redirect parsed Autodiscover response
+ * will be stored here.
+ *
+ * @var mixed
+ */
+ public $discovered = null;
+
+ /**
+ * Constructor for the EWSAutodiscover class.
+ *
+ * @param string $email
+ * @param string $password
+ * @param string $username
+ * If left blank, the email provided will be used.
+ */
+ public function __construct($email, $password, $username = null)
+ {
+ $this->email = $email;
+ $this->password = $password;
+ if ($username === null) {
+ $this->username = $email;
+ } else {
+ $this->username = $username;
+ }
+
+ $this->setTLD();
+ }
+
+ /**
+ * Execute the full discovery chain of events in the correct sequence
+ * until a valid response is received, or all methods have failed.
+ *
+ * @return integer
+ * One of the AUTODISCOVERED_VIA_* constants.
+ *
+ * @throws \RuntimeException
+ * When all autodiscovery methods fail.
+ */
+ public function discover()
+ {
+ $result = $this->tryTLD();
+
+ if ($result === false) {
+ $result = $this->trySubdomain();
+ }
+
+ if ($result === false) {
+ $result = $this->trySubdomainUnauthenticatedGet();
+ }
+
+ if ($result === false) {
+ $result = $this->trySRVRecord();
+ }
+
+ if ($result === false) {
+ throw new \RuntimeException('Autodiscovery failed.');
+ }
+
+ return $result;
+ }
+
+ /**
+ * Return the settings discovered from the Autodiscover process.
+ *
+ * NULL indicates discovery has not completed (or been attempted)
+ * FALSE indicates discovery was not successful. Check for errors
+ * or redirects.
+ * An array will be returned with discovered settings on success.
+ *
+ * @return mixed
+ */
+ public function discoveredSettings()
+ {
+ return $this->discovered;
+ }
+
+ /**
+ * Toggle skipping of SSL verification in cURL requests.
+ *
+ * @param boolean $skip
+ * Whether or not to skip SSL certificate verification.
+ * @return self
+ */
+ public function skipSSLVerification($skip = true)
+ {
+ $this->skip_ssl_verification = (bool) $skip;
+
+ return $this;
+ }
+
+ /**
+ * Parse the hex ServerVersion value and return a valid
+ * Client::VERSION_* constant.
+ *
+ * @return string|boolean A known version constant, or FALSE if it could not
+ * be determined.
+ *
+ * @link http://msdn.microsoft.com/en-us/library/bb204122(v=exchg.140).aspx
+ * @link http://blogs.msdn.com/b/pcreehan/archive/2009/09/21/parsing-serverversion-when-an-int-is-really-5-ints.aspx
+ * @link http://office.microsoft.com/en-us/outlook-help/determine-the-version-of-microsoft-exchange-server-my-account-connects-to-HA001191800.aspx
+ *
+ * @param string $version_hex
+ * Hexadecimal version string.
+ */
+ public function parseServerVersion($version_hex)
+ {
+ $svbinary = base_convert($version_hex, 16, 2);
+ if (strlen($svbinary) == 31) {
+ $svbinary = '0' . $svbinary;
+ }
+
+ $majorversion = base_convert(substr($svbinary, 4, 6), 2, 10);
+ $minorversion = base_convert(substr($svbinary, 10, 6), 2, 10);
+ $majorbuild = base_convert(substr($svbinary, 17, 15), 2, 10);
+
+ switch ($majorversion) {
+ case 8:
+ return $this->parseVersion2007($minorversion);
+ case 14:
+ return $this->parseVersion2010($minorversion);
+ case 15:
+ if ($minorversion == 0) {
+ return $this->parseVersion2013($majorbuild);
+ }
+
+ return $this->parseVersion2016();
+ }
+
+ // Guess we didn't find a known version.
+ return false;
+ }
+
+ /**
+ * Method to return a new Client object, auto-configured
+ * with the proper hostname.
+ *
+ * @return mixed Client object on success, FALSE on failure.
+ */
+ public function newEWS()
+ {
+ // Discovery not yet attempted.
+ if ($this->discovered === null) {
+ $this->discover();
+ }
+
+ // Discovery not successful.
+ if ($this->discovered === false) {
+ return false;
+ }
+
+ $server = false;
+ $version = null;
+
+ // Pick out the host from the EXPR (Exchange RPC over HTTP).
+ foreach ($this->discovered['Account']['Protocol'] as $protocol) {
+ if (
+ ($protocol['Type'] == 'EXCH' || $protocol['Type'] == 'EXPR')
+ && isset($protocol['ServerVersion'])
+ ) {
+ if ($version === null) {
+ $sv = $this->parseServerVersion($protocol['ServerVersion']);
+ if ($sv !== false) {
+ $version = $sv;
+ }
+ }
+ }
+
+ if ($protocol['Type'] == 'EXPR' && isset($protocol['Server'])) {
+ $server = $protocol['Server'];
+ }
+ }
+
+ if ($server) {
+ if ($version === null) {
+ // EWS class default.
+ $version = Client::VERSION_2007;
+ }
+ return new Client(
+ $server,
+ (!empty($this->username) ? $this->username : $this->email),
+ $this->password,
+ $version
+ );
+ }
+
+ return false;
+ }
+
+ /**
+ * Static method may fail if there are issues surrounding SSL certificates.
+ * In such cases, set up the object as needed, and then call newEWS().
+ *
+ * @param string $email
+ * @param string $password
+ * @param string $username
+ * If left blank, the email provided will be used.
+ * @return mixed
+ */
+ public static function getEWS($email, $password, $username = null)
+ {
+ $auto = new Autodiscover($email, $password, $username);
+ return $auto->newEWS();
+ }
+
+ /**
+ * Perform an NTLM authenticated HTTPS POST to the top-level
+ * domain of the email address.
+ *
+ * @return integer|boolean
+ * One of the AUTODISCOVERED_VIA_* constants or false on failure.
+ */
+ public function tryTLD()
+ {
+ $url = 'https://' . $this->tld . self::AUTODISCOVER_PATH;
+ return ($this->tryViaUrl($url) ? self::AUTODISCOVERED_VIA_TLD : false);
+ }
+
+ /**
+ * Perform an NTLM authenticated HTTPS POST to the 'autodiscover'
+ * subdomain of the email address' TLD.
+ *
+ * @return integer|boolean
+ * One of the AUTODISCOVERED_VIA_* constants or false on failure.
+ */
+ public function trySubdomain()
+ {
+ $url = 'https://autodiscover.' . $this->tld . self::AUTODISCOVER_PATH;
+ return ($this->tryViaUrl($url)
+ ? self::AUTODISCOVERED_VIA_SUBDOMAIN
+ : false);
+ }
+
+ /**
+ * Perform an unauthenticated HTTP GET in an attempt to get redirected
+ * via 302 to the correct location to perform the HTTPS POST.
+ *
+ * @return integer|boolean
+ * One of the AUTODISCOVERED_VIA_* constants or false on failure.
+ */
+ public function trySubdomainUnauthenticatedGet()
+ {
+ $this->reset();
+ $url = 'http://autodiscover.' . $this->tld . self::AUTODISCOVER_PATH;
+ $ch = curl_init();
+ $opts = array(
+ CURLOPT_URL => $url,
+ CURLOPT_HTTPGET => true,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_TIMEOUT => 4,
+ CURLOPT_CONNECTTIMEOUT => $this->connection_timeout,
+ CURLOPT_FOLLOWLOCATION => false,
+ CURLOPT_HEADER => false,
+ CURLOPT_HEADERFUNCTION => array($this, 'readHeaders'),
+ CURLOPT_HTTP200ALIASES => array(301, 302),
+ CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4
+ );
+ curl_setopt_array($ch, $opts);
+ $this->last_response = curl_exec($ch);
+ $this->last_info = curl_getinfo($ch);
+ $this->last_curl_errno = curl_errno($ch);
+ $this->last_curl_error = curl_error($ch);
+
+ if (
+ $this->last_info['http_code'] == 302
+ || $this->last_info['http_code'] == 301
+ ) {
+ if ($this->tryViaUrl($this->last_response_headers['location'])) {
+ return self::AUTODISCOVERED_VIA_UNAUTHENTICATED_GET;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Attempt to retrieve the autodiscover host from an SRV DNS record.
+ *
+ * @link http://support.microsoft.com/kb/940881
+ *
+ * @return integer|boolean
+ * The value of self::AUTODISCOVERED_VIA_SRV_RECORD or false.
+ */
+ public function trySRVRecord()
+ {
+ $srvhost = '_autodiscover._tcp.' . $this->tld;
+ $lookup = dns_get_record($srvhost, DNS_SRV);
+ if (sizeof($lookup) > 0) {
+ $host = $lookup[0]['target'];
+ $url = 'https://' . $host . self::AUTODISCOVER_PATH;
+ if ($this->tryViaUrl($url)) {
+ return self::AUTODISCOVERED_VIA_SRV_RECORD;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the path to the file to be used by CURLOPT_CAINFO.
+ *
+ * @param string $path
+ * Path to a certificate file such as cacert.pem
+ * @return self
+ */
+ public function setCAInfo($path)
+ {
+ if (file_exists($path) && is_file($path)) {
+ $this->cainfo = $path;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set the path to the file to be used by CURLOPT_CAPATH.
+ *
+ * @param string $path
+ * Path to a directory containing one or more CA certificates.
+ * @return self
+ */
+ public function setCAPath($path)
+ {
+ if (is_dir($path)) {
+ $this->capath = $path;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Set a connection timeout for the POST methods.
+ *
+ * @param integer $seconds
+ * Seconds to wait for a connection.
+ * @return self
+ */
+ public function setConnectionTimeout($seconds)
+ {
+ $this->connection_timeout = intval($seconds);
+
+ return $this;
+ }
+
+ /**
+ * Perform the NTLM authenticated post against one of the chosen
+ * endpoints.
+ *
+ * @param string $url
+ * URL to try posting to.
+ * @param integer $timeout
+ * Number of seconds before the request should timeout.
+ * @return boolean
+ */
+ public function doNTLMPost($url, $timeout = 6)
+ {
+ $this->reset();
+
+ $ch = curl_init();
+ $opts = array(
+ CURLOPT_URL => $url,
+ CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_NTLM,
+ CURLOPT_CUSTOMREQUEST => 'POST',
+ CURLOPT_POSTFIELDS => $this->getAutoDiscoverRequest(),
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_USERPWD => $this->username . ':' . $this->password,
+ CURLOPT_TIMEOUT => $timeout,
+ CURLOPT_CONNECTTIMEOUT => $this->connection_timeout,
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_HEADER => false,
+ CURLOPT_HEADERFUNCTION => array($this, 'readHeaders'),
+ CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLOPT_SSL_VERIFYHOST => 2,
+ );
+
+ // Set the appropriate content-type.
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml; charset=utf-8'));
+
+ if (!empty($this->cainfo)) {
+ $opts[CURLOPT_CAINFO] = $this->cainfo;
+ }
+
+ if (!empty($this->capath)) {
+ $opts[CURLOPT_CAPATH] = $this->capath;
+ }
+
+ if ($this->skip_ssl_verification) {
+ $opts[CURLOPT_SSL_VERIFYPEER] = false;
+ }
+
+ curl_setopt_array($ch, $opts);
+ $this->last_response = curl_exec($ch);
+ $this->last_info = curl_getinfo($ch);
+ $this->last_curl_errno = curl_errno($ch);
+ $this->last_curl_error = curl_error($ch);
+
+ if ($this->last_curl_errno != CURLE_OK) {
+ return false;
+ }
+
+ $discovered = $this->parseAutodiscoverResponse();
+
+ return $discovered;
+ }
+
+ /**
+ * Parse the Autoresponse Payload, particularly to determine if an
+ * additional request is necessary.
+ *
+ * @return boolean|array FALSE if response isn't XML or parsed response
+ * array.
+ */
+ protected function parseAutodiscoverResponse()
+ {
+ // Content-type isn't trustworthy, unfortunately. Shame on Microsoft.
+ if (substr($this->last_response, 0, 5) !== '<?xml') {
+ return false;
+ }
+
+ $response = $this->responseToArray($this->last_response);
+
+ if (isset($response['Error'])) {
+ $this->error = $response['Error'];
+ return false;
+ }
+
+ // Check the account action for redirect.
+ switch ($response['Account']['Action']) {
+ case 'redirectUrl':
+ $this->redirect = array(
+ 'redirectUrl' => $response['Account']['RedirectUrl']
+ );
+ return false;
+ case 'redirectAddr':
+ $this->redirect = array(
+ 'redirectAddr' => $response['Account']['RedirectAddr']
+ );
+ return false;
+ case 'settings':
+ default:
+ $this->discovered = $response;
+ return true;
+ }
+ }
+
+ /**
+ * Set the top-level domain to be used with autodiscover attempts based
+ * on the provided email address.
+ *
+ * @return boolean
+ */
+ protected function setTLD()
+ {
+ $pos = strpos($this->email, '@');
+ if ($pos !== false) {
+ $this->tld = trim(substr($this->email, $pos + 1));
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Reset the response-related structures. Called before making a new
+ * request.
+ *
+ * @return self
+ */
+ public function reset()
+ {
+ $this->last_response_headers = array();
+ $this->last_info = array();
+ $this->last_curl_errno = 0;
+ $this->last_curl_error = '';
+
+ return $this;
+ }
+
+ /**
+ * Return the generated Autodiscover XML request body.
+ *
+ * @return string
+ */
+ public function getAutodiscoverRequest()
+ {
+ if (!empty($this->requestxml)) {
+ return $this->requestxml;
+ }
+
+ $xml = new \XMLWriter();
+ $xml->openMemory();
+ $xml->setIndent(true);
+ $xml->startDocument('1.0', 'UTF-8');
+ $xml->startElementNS(
+ null,
+ 'Autodiscover',
+ 'http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006'
+ );
+
+ $xml->startElement('Request');
+ $xml->writeElement('EMailAddress', $this->email);
+ $xml->writeElement(
+ 'AcceptableResponseSchema',
+ 'http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a'
+ );
+ $xml->endElement();
+ $xml->endElement();
+
+ $this->requestxml = $xml->outputMemory();
+ return $this->requestxml;
+ }
+
+ /**
+ * Utility function to pick headers off of the incoming cURL response.
+ * Used with CURLOPT_HEADERFUNCTION.
+ *
+ * @param resource $_ch
+ * cURL handle.
+ * @param string $str
+ * Header string to read.
+ * @return integer
+ * Bytes read.
+ */
+ public function readHeaders($_ch, $str)
+ {
+ $pos = strpos($str, ':');
+ if ($pos !== false) {
+ $key = strtolower(substr($str, 0, $pos));
+ $val = trim(substr($str, $pos + 1));
+ $this->last_response_headers[$key] = $val;
+ }
+
+ return strlen($str);
+ }
+
+ /**
+ * Utility function to parse XML payloads from the response into easier
+ * to manage associative arrays.
+ *
+ * @param string $xml
+ * XML to parse.
+ * @return array
+ */
+ public function responseToArray($xml)
+ {
+ $doc = new \DOMDocument();
+ $doc->loadXML($xml);
+ $out = $this->nodeToArray($doc->documentElement);
+
+ return $out['Response'];
+ }
+
+ /**
+ * Recursive method for parsing DOM nodes.
+ *
+ * @param \DOMElement $node
+ * DOMNode object.
+ * @return mixed
+ *
+ * @link https://github.com/gaarf/XML-string-to-PHP-array
+ */
+ protected function nodeToArray($node)
+ {
+ $output = array();
+ switch ($node->nodeType) {
+ case XML_CDATA_SECTION_NODE:
+ case XML_TEXT_NODE:
+ $output = trim($node->textContent);
+ break;
+ case XML_ELEMENT_NODE:
+ for ($i = 0, $m = $node->childNodes->length; $i < $m; $i++) {
+ $child = $node->childNodes->item($i);
+ $v = $this->nodeToArray($child);
+ if (isset($child->tagName)) {
+ $t = $child->tagName;
+ if (!isset($output[$t])) {
+ $output[$t] = array();
+ }
+ $output[$t][] = $v;
+ } elseif ($v || $v === '0') {
+ $output = (string) $v;
+ }
+ }
+
+ // Edge case of a node containing a text node, which also has
+ // attributes. this way we'll retain text and attributes for
+ // this node.
+ if (is_string($output) && $node->attributes->length) {
+ $output = array('@text' => $output);
+ }
+
+ if (is_array($output)) {
+ if ($node->attributes->length) {
+ $a = array();
+ foreach ($node->attributes as $attrName => $attrNode) {
+ $a[$attrName] = (string) $attrNode->value;
+ }
+ $output['@attributes'] = $a;
+ }
+ foreach ($output as $t => $v) {
+ if (is_array($v) && count($v) == 1 && $t != '@attributes') {
+ $output[$t] = $v[0];
+ }
+ }
+ }
+ break;
+ }
+
+ return $output;
+ }
+
+ /**
+ * Parses the version of an Exchange 2007 server.
+ *
+ * @param integer $minorversion
+ * Minor server version.
+ * @return string Server version.
+ */
+ protected function parseVersion2007($minorversion) {
+ switch ($minorversion) {
+ case 0:
+ return Client::VERSION_2007;
+ case 1:
+ case 2:
+ case 3:
+ return Client::VERSION_2007_SP1;
+ default:
+ return Client::VERSION_2007;
+ }
+ }
+
+ /**
+ * Parses the version of an Exchange 2010 server.
+ *
+ * @param integer $minorversion
+ * Minor server version.
+ * @return string Server version.
+ */
+ protected function parseVersion2010($minorversion) {
+ switch ($minorversion) {
+ case 0:
+ return Client::VERSION_2010;
+ case 1:
+ return Client::VERSION_2010_SP1;
+ case 2:
+ return Client::VERSION_2010_SP2;
+ default:
+ return Client::VERSION_2010;
+ }
+ }
+
+ /**
+ * Parses the version of an Exchange 2013 server.
+ *
+ * @param integer $majorbuild
+ * Major build version.
+ * @return string Server version.
+ */
+ protected function parseVersion2013($majorbuild) {
+ return ($majorbuild == 847
+ ? Client::VERSION_2013_SP1
+ : Client::VERSION_2013);
+ }
+
+ /**
+ * Parses the version of an Exchange 2016 server.
+ *
+ * @return string Server version.
+ */
+ protected function parseVersion2016() {
+ return Client::VERSION_2016;
+ }
+
+ /**
+ * Attempts an autodiscover via a URL.
+ *
+ * @param string $url
+ * Url to attempt an autodiscover.
+ * @param integer $timeout
+ * Number of seconds before the request should timeout.
+ * @return boolean
+ */
+ protected function tryViaUrl($url, $timeout = 6)
+ {
+ $result = $this->doNTLMPost($url, $timeout);
+ return ($result ? true : false);
+ }
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ClassMap.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ClassMap.php
new file mode 100644
index 00000000..cde1cbb8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ClassMap.php
@@ -0,0 +1,684 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ClassMap.
+ *
+ * This class is generated using the build-classmap.php script. To make changes
+ * to this file should be made there or in the ClassMap.mustache template.
+ *
+ * Last updated on: 2017-03-03 00:53:44 UTC
+ */
+
+namespace jamesiarmes\PhpEws;
+
+/**
+ * Mapping of complex types to class implementations.
+ *
+ * @package php-ews\ClassMap
+ */
+class ClassMap {
+ public static function getMap() {
+ return array(
+ // Map for ArrayType classes.
+ 'ArrayOfRecipientTrackingEventType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRecipientTrackingEventType',
+ 'ArrayOfDLExpansionType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfDLExpansionType',
+ 'NonEmptyArrayOfMailboxQueriesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfMailboxQueriesType',
+ 'NonEmptyArrayOfBaseItemIdsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfBaseItemIdsType',
+ 'ArrayOfAppsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfAppsType',
+ 'NonEmptyArrayOfNotificationEventTypesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfNotificationEventTypesType',
+ 'ArrayOfTimeZoneDefinitionType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfTimeZoneDefinitionType',
+ 'ArrayOfPhoneNumberAttributedValuesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfPhoneNumberAttributedValuesType',
+ 'NonEmptyArrayOfPropertyValuesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfPropertyValuesType',
+ 'ArrayOfPrivateCatalogAddInsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfPrivateCatalogAddInsType',
+ 'NonEmptyArrayOfItemChangeDescriptionsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfItemChangeDescriptionsType',
+ 'NonEmptyArrayOfDeletedOccurrencesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfDeletedOccurrencesType',
+ 'NonEmptyArrayOfFolderChangesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfFolderChangesType',
+ 'NonEmptyArrayOfExtendedFieldURIs' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfExtendedFieldURIs',
+ 'ArrayOfTrackingPropertiesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfTrackingPropertiesType',
+ 'ArrayOfSearchPreviewItemsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfSearchPreviewItemsType',
+ 'ArrayOfRuleOperationErrorsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRuleOperationErrorsType',
+ 'ArrayOfPersonaAttributionsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfPersonaAttributionsType',
+ 'NonEmptyArrayOfReminderItemActionType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfReminderItemActionType',
+ 'ArrayOfResponseMessagesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfResponseMessagesType',
+ 'ArrayOfPermissionsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfPermissionsType',
+ 'ArrayOfSmtpAddressType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfSmtpAddressType',
+ 'ArrayOfFailedSearchMailboxesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfFailedSearchMailboxesType',
+ 'NonEmptyArrayOfMailboxSearchScopesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfMailboxSearchScopesType',
+ 'ArrayOfUnknownEntriesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfUnknownEntriesType',
+ 'ArrayOfRoomsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRoomsType',
+ 'ArrayOfStringAttributedValuesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfStringAttributedValuesType',
+ 'NonEmptyArrayOfNotificationsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfNotificationsType',
+ 'ArrayOfServiceConfigurationResponseMessageType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfServiceConfigurationResponseMessageType',
+ 'ArrayOfUserMailboxesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfUserMailboxesType',
+ 'NonEmptyArrayOfGroupIdentifiersType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfGroupIdentifiersType',
+ 'ArrayOfExtendedPropertyAttributedValueType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfExtendedPropertyAttributedValueType',
+ 'ArrayOfMailboxData' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfMailboxData',
+ 'ArrayOfValueAttributionsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfValueAttributionsType',
+ 'ArrayOfDiscoverySearchConfigurationType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfDiscoverySearchConfigurationType',
+ 'ArrayOfCalendarPermissionsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfCalendarPermissionsType',
+ 'ArrayOfAttendeeConflictData' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfAttendeeConflictData',
+ 'ArrayOfItemClassType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfItemClassType',
+ 'ArrayOfWorkingPeriod' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfWorkingPeriod',
+ 'NonEmptyArrayOfPeriodsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfPeriodsType',
+ 'NonEmptyArrayOfAllItemsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfAllItemsType',
+ 'ArrayOfSuggestion' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfSuggestion',
+ 'ArrayOfBinaryType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfBinaryType',
+ 'ArrayOfPeopleQuerySource' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfPeopleQuerySource',
+ 'ArrayOfPostalAddressAttributedValuesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfPostalAddressAttributedValuesType',
+ 'ArrayOfUserIdType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfUserIdType',
+ 'ArrayOfBaseItemIdsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfBaseItemIdsType',
+ 'ArrayOfProtectionRulesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfProtectionRulesType',
+ 'ArrayOfRecipientsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRecipientsType',
+ 'ArrayOfFindMessageTrackingSearchResultType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfFindMessageTrackingSearchResultType',
+ 'ArrayOfRetentionPolicyTagsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRetentionPolicyTagsType',
+ 'NonEmptyArrayOfFieldOrdersType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfFieldOrdersType',
+ 'ArrayOfContextProperty' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfContextProperty',
+ 'ArrayOfEncryptedSharedFolderDataType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfEncryptedSharedFolderDataType',
+ 'NonEmptyArrayOfAlternateIdsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfAlternateIdsType',
+ 'ArrayOfFolderIdType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfFolderIdType',
+ 'ArrayOfServiceConfigurationType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfServiceConfigurationType',
+ 'NonEmptyArrayOfFoldersType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfFoldersType',
+ 'ArrayOfStringsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfStringsType',
+ 'NonEmptyArrayOfInternetHeadersType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfInternetHeadersType',
+ 'ArrayOfImGroupType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfImGroupType',
+ 'NonEmptyArrayOfExtendedPropertyType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfExtendedPropertyType',
+ 'ArrayOfOccurrenceRangesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfOccurrenceRangesType',
+ 'ArrayOfArraysOfTrackingPropertiesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfArraysOfTrackingPropertiesType',
+ 'ArrayOfRuleValidationErrorsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRuleValidationErrorsType',
+ 'ArrayOfEmailAddressAttributedValuesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfEmailAddressAttributedValuesType',
+ 'NonEmptyArrayOfTimeZoneIdType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfTimeZoneIdType',
+ 'ArrayOfRemindersType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRemindersType',
+ 'ArrayOfSearchableMailboxesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfSearchableMailboxesType',
+ 'NonEmptyArrayOfAttendeesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfAttendeesType',
+ 'ArrayOfGroupedItemsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfGroupedItemsType',
+ 'ArrayOfResolutionType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfResolutionType',
+ 'ArrayOfInvalidRecipientsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfInvalidRecipientsType',
+ 'ArrayOfSuggestionDayResult' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfSuggestionDayResult',
+ 'NonEmptyArrayofLegacyDNsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayofLegacyDNsType',
+ 'ArrayOfMailboxHoldStatusType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfMailboxHoldStatusType',
+ 'NonEmptyArrayOfOccurrenceInfoType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfOccurrenceInfoType',
+ 'ArrayOfNonIndexableItemDetailsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfNonIndexableItemDetailsType',
+ 'NonEmptyArrayOfApplyConversationActionType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfApplyConversationActionType',
+ 'ArrayOfRuleOperationsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRuleOperationsType',
+ 'ArrayOfPeopleType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfPeopleType',
+ 'ArrayOfDelegateUserType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfDelegateUserType',
+ 'ArrayOfBodyContentAttributedValuesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfBodyContentAttributedValuesType',
+ 'ArrayOfAppManifestsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfAppManifestsType',
+ 'NonEmptyArrayOfUploadItemsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfUploadItemsType',
+ 'ArrayOfConversationNodesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfConversationNodesType',
+ 'ArrayOfMailTipsResponseMessageType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfMailTipsResponseMessageType',
+ 'NonEmptyArrayOfRestrictedGroupIdentifiersType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfRestrictedGroupIdentifiersType',
+ 'ArrayOfEmailAddressesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfEmailAddressesType',
+ 'ArrayOfDelegateUserResponseMessageType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfDelegateUserResponseMessageType',
+ 'ArrayOfRealItemsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRealItemsType',
+ 'NonEmptyArrayOfFolderNamesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfFolderNamesType',
+ 'ArrayOfFreeBusyResponse' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfFreeBusyResponse',
+ 'NonEmptyArrayOfItemChangesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfItemChangesType',
+ 'ArrayOfSearchItemKindsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfSearchItemKindsType',
+ 'NonEmptyArrayOfResponseObjectsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfResponseObjectsType',
+ 'ArrayOfAttachmentsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfAttachmentsType',
+ 'ArrayOfRulesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfRulesType',
+ 'ArrayOfCalendarEvent' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfCalendarEvent',
+ 'NonEmptyArrayOfRequestAttachmentIdsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfRequestAttachmentIdsType',
+ 'NonEmptyArrayOfAttachmentsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfAttachmentsType',
+ 'NonEmptyArrayOfBaseFolderIdsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfBaseFolderIdsType',
+ 'NonEmptyArrayOfPathsToElementType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfPathsToElementType',
+ 'ArrayOfTransitionsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfTransitionsType',
+ 'ArrayOfExtendedAttributesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfExtendedAttributesType',
+ 'NonEmptyArrayOfFolderChangeDescriptionsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfFolderChangeDescriptionsType',
+ 'ArrayOfConversationsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfConversationsType',
+ 'NonEmptyArrayOfClientAccessTokenRequestsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfClientAccessTokenRequestsType',
+ 'ArrayOfTransitionsGroupsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfTransitionsGroupsType',
+ 'ArrayOfNonIndexableItemStatisticsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfNonIndexableItemStatisticsType',
+ 'ArrayOfFoldersType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfFoldersType',
+ 'ArrayOfStringArrayAttributedValuesType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfStringArrayAttributedValuesType',
+ 'NonEmptyArrayOfSubscriptionIdsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfSubscriptionIdsType',
+ 'NonEmptyArrayOfItemIdsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\NonEmptyArrayOfItemIdsType',
+ 'ArrayOfKeywordStatisticsSearchResultsType' => '\\jamesiarmes\\PhpEws\\ArrayType\\ArrayOfKeywordStatisticsSearchResultsType',
+ // Map for Request classes.
+ 'EmptyFolderType' => '\\jamesiarmes\\PhpEws\\Request\\EmptyFolderType',
+ 'GetDelegateType' => '\\jamesiarmes\\PhpEws\\Request\\GetDelegateType',
+ 'CreateAttachmentType' => '\\jamesiarmes\\PhpEws\\Request\\CreateAttachmentType',
+ 'GetMessageTrackingReportRequestType' => '\\jamesiarmes\\PhpEws\\Request\\GetMessageTrackingReportRequestType',
+ 'DeleteItemType' => '\\jamesiarmes\\PhpEws\\Request\\DeleteItemType',
+ 'RemoveDelegateType' => '\\jamesiarmes\\PhpEws\\Request\\RemoveDelegateType',
+ 'AddImGroupType' => '\\jamesiarmes\\PhpEws\\Request\\AddImGroupType',
+ 'ResolveNamesType' => '\\jamesiarmes\\PhpEws\\Request\\ResolveNamesType',
+ 'GetInboxRulesRequestType' => '\\jamesiarmes\\PhpEws\\Request\\GetInboxRulesRequestType',
+ 'GetImItemListType' => '\\jamesiarmes\\PhpEws\\Request\\GetImItemListType',
+ 'SetUserOofSettingsRequest' => '\\jamesiarmes\\PhpEws\\Request\\SetUserOofSettingsRequest',
+ 'GetAppManifestsType' => '\\jamesiarmes\\PhpEws\\Request\\GetAppManifestsType',
+ 'FindPeopleType' => '\\jamesiarmes\\PhpEws\\Request\\FindPeopleType',
+ 'FindConversationType' => '\\jamesiarmes\\PhpEws\\Request\\FindConversationType',
+ 'FindMessageTrackingReportRequestType' => '\\jamesiarmes\\PhpEws\\Request\\FindMessageTrackingReportRequestType',
+ 'GetEventsType' => '\\jamesiarmes\\PhpEws\\Request\\GetEventsType',
+ 'PlayOnPhoneType' => '\\jamesiarmes\\PhpEws\\Request\\PlayOnPhoneType',
+ 'RemoveContactFromImListType' => '\\jamesiarmes\\PhpEws\\Request\\RemoveContactFromImListType',
+ 'GetPhoneCallInformationType' => '\\jamesiarmes\\PhpEws\\Request\\GetPhoneCallInformationType',
+ 'UpdateFolderType' => '\\jamesiarmes\\PhpEws\\Request\\UpdateFolderType',
+ 'GetClientAccessTokenType' => '\\jamesiarmes\\PhpEws\\Request\\GetClientAccessTokenType',
+ 'GetAppMarketplaceUrl' => '\\jamesiarmes\\PhpEws\\Request\\GetAppMarketplaceUrl',
+ 'ConvertIdType' => '\\jamesiarmes\\PhpEws\\Request\\ConvertIdType',
+ 'DisconnectPhoneCallType' => '\\jamesiarmes\\PhpEws\\Request\\DisconnectPhoneCallType',
+ 'GetAttachmentType' => '\\jamesiarmes\\PhpEws\\Request\\GetAttachmentType',
+ 'CreateUserConfigurationType' => '\\jamesiarmes\\PhpEws\\Request\\CreateUserConfigurationType',
+ 'DeleteUserConfigurationType' => '\\jamesiarmes\\PhpEws\\Request\\DeleteUserConfigurationType',
+ 'CreateItemType' => '\\jamesiarmes\\PhpEws\\Request\\CreateItemType',
+ 'FindItemType' => '\\jamesiarmes\\PhpEws\\Request\\FindItemType',
+ 'GetUserConfigurationType' => '\\jamesiarmes\\PhpEws\\Request\\GetUserConfigurationType',
+ 'GetUserAvailabilityRequestType' => '\\jamesiarmes\\PhpEws\\Request\\GetUserAvailabilityRequestType',
+ 'PerformReminderActionType' => '\\jamesiarmes\\PhpEws\\Request\\PerformReminderActionType',
+ 'GetRemindersType' => '\\jamesiarmes\\PhpEws\\Request\\GetRemindersType',
+ 'GetImItemsType' => '\\jamesiarmes\\PhpEws\\Request\\GetImItemsType',
+ 'SyncFolderItemsType' => '\\jamesiarmes\\PhpEws\\Request\\SyncFolderItemsType',
+ 'MoveItemType' => '\\jamesiarmes\\PhpEws\\Request\\MoveItemType',
+ 'DeleteAttachmentType' => '\\jamesiarmes\\PhpEws\\Request\\DeleteAttachmentType',
+ 'CopyFolderType' => '\\jamesiarmes\\PhpEws\\Request\\CopyFolderType',
+ 'RefreshSharingFolderType' => '\\jamesiarmes\\PhpEws\\Request\\RefreshSharingFolderType',
+ 'UninstallAppType' => '\\jamesiarmes\\PhpEws\\Request\\UninstallAppType',
+ 'GetSharingFolderType' => '\\jamesiarmes\\PhpEws\\Request\\GetSharingFolderType',
+ 'GetUserPhotoType' => '\\jamesiarmes\\PhpEws\\Request\\GetUserPhotoType',
+ 'ExpandDLType' => '\\jamesiarmes\\PhpEws\\Request\\ExpandDLType',
+ 'GetPasswordExpirationDateType' => '\\jamesiarmes\\PhpEws\\Request\\GetPasswordExpirationDateType',
+ 'RemoveImGroupType' => '\\jamesiarmes\\PhpEws\\Request\\RemoveImGroupType',
+ 'AddDistributionGroupToImListType' => '\\jamesiarmes\\PhpEws\\Request\\AddDistributionGroupToImListType',
+ 'RemoveImContactFromGroupType' => '\\jamesiarmes\\PhpEws\\Request\\RemoveImContactFromGroupType',
+ 'GetServerTimeZonesType' => '\\jamesiarmes\\PhpEws\\Request\\GetServerTimeZonesType',
+ 'FindMailboxStatisticsByKeywordsType' => '\\jamesiarmes\\PhpEws\\Request\\FindMailboxStatisticsByKeywordsType',
+ 'SubscribeType' => '\\jamesiarmes\\PhpEws\\Request\\SubscribeType',
+ 'SetImGroupType' => '\\jamesiarmes\\PhpEws\\Request\\SetImGroupType',
+ 'DisableAppType' => '\\jamesiarmes\\PhpEws\\Request\\DisableAppType',
+ 'BaseMoveCopyItemType' => '\\jamesiarmes\\PhpEws\\Request\\BaseMoveCopyItemType',
+ 'GetSharingMetadataType' => '\\jamesiarmes\\PhpEws\\Request\\GetSharingMetadataType',
+ 'GetHoldOnMailboxesType' => '\\jamesiarmes\\PhpEws\\Request\\GetHoldOnMailboxesType',
+ 'AddNewTelUriContactToGroupType' => '\\jamesiarmes\\PhpEws\\Request\\AddNewTelUriContactToGroupType',
+ 'GetUserRetentionPolicyTagsType' => '\\jamesiarmes\\PhpEws\\Request\\GetUserRetentionPolicyTagsType',
+ 'InstallAppType' => '\\jamesiarmes\\PhpEws\\Request\\InstallAppType',
+ 'SetHoldOnMailboxesType' => '\\jamesiarmes\\PhpEws\\Request\\SetHoldOnMailboxesType',
+ 'CreateManagedFolderRequestType' => '\\jamesiarmes\\PhpEws\\Request\\CreateManagedFolderRequestType',
+ 'DeleteFolderType' => '\\jamesiarmes\\PhpEws\\Request\\DeleteFolderType',
+ 'GetRoomsType' => '\\jamesiarmes\\PhpEws\\Request\\GetRoomsType',
+ 'UpdateUserConfigurationType' => '\\jamesiarmes\\PhpEws\\Request\\UpdateUserConfigurationType',
+ 'GetRoomListsType' => '\\jamesiarmes\\PhpEws\\Request\\GetRoomListsType',
+ 'BaseMoveCopyFolderType' => '\\jamesiarmes\\PhpEws\\Request\\BaseMoveCopyFolderType',
+ 'GetStreamingEventsType' => '\\jamesiarmes\\PhpEws\\Request\\GetStreamingEventsType',
+ 'AddDelegateType' => '\\jamesiarmes\\PhpEws\\Request\\AddDelegateType',
+ 'MoveFolderType' => '\\jamesiarmes\\PhpEws\\Request\\MoveFolderType',
+ 'GetSearchableMailboxesType' => '\\jamesiarmes\\PhpEws\\Request\\GetSearchableMailboxesType',
+ 'GetDiscoverySearchConfigurationType' => '\\jamesiarmes\\PhpEws\\Request\\GetDiscoverySearchConfigurationType',
+ 'FindFolderType' => '\\jamesiarmes\\PhpEws\\Request\\FindFolderType',
+ 'ArchiveItemType' => '\\jamesiarmes\\PhpEws\\Request\\ArchiveItemType',
+ 'GetNonIndexableItemDetailsType' => '\\jamesiarmes\\PhpEws\\Request\\GetNonIndexableItemDetailsType',
+ 'UnsubscribeType' => '\\jamesiarmes\\PhpEws\\Request\\UnsubscribeType',
+ 'BaseRequestType' => '\\jamesiarmes\\PhpEws\\Request\\BaseRequestType',
+ 'GetUserOofSettingsRequest' => '\\jamesiarmes\\PhpEws\\Request\\GetUserOofSettingsRequest',
+ 'SearchMailboxesType' => '\\jamesiarmes\\PhpEws\\Request\\SearchMailboxesType',
+ 'GetConversationItemsType' => '\\jamesiarmes\\PhpEws\\Request\\GetConversationItemsType',
+ 'GetPersonaType' => '\\jamesiarmes\\PhpEws\\Request\\GetPersonaType',
+ 'CreateFolderType' => '\\jamesiarmes\\PhpEws\\Request\\CreateFolderType',
+ 'GetMailTipsType' => '\\jamesiarmes\\PhpEws\\Request\\GetMailTipsType',
+ 'GetItemType' => '\\jamesiarmes\\PhpEws\\Request\\GetItemType',
+ 'ApplyConversationActionType' => '\\jamesiarmes\\PhpEws\\Request\\ApplyConversationActionType',
+ 'RemoveDistributionGroupFromImListType' => '\\jamesiarmes\\PhpEws\\Request\\RemoveDistributionGroupFromImListType',
+ 'SyncFolderHierarchyType' => '\\jamesiarmes\\PhpEws\\Request\\SyncFolderHierarchyType',
+ 'AddNewImContactToGroup' => '\\jamesiarmes\\PhpEws\\Request\\AddNewImContactToGroup',
+ 'ExportItemsType' => '\\jamesiarmes\\PhpEws\\Request\\ExportItemsType',
+ 'CreateFolderPathType' => '\\jamesiarmes\\PhpEws\\Request\\CreateFolderPathType',
+ 'GetFolderType' => '\\jamesiarmes\\PhpEws\\Request\\GetFolderType',
+ 'UploadItemsType' => '\\jamesiarmes\\PhpEws\\Request\\UploadItemsType',
+ 'UpdateInboxRulesRequestType' => '\\jamesiarmes\\PhpEws\\Request\\UpdateInboxRulesRequestType',
+ 'GetNonIndexableItemStatisticsType' => '\\jamesiarmes\\PhpEws\\Request\\GetNonIndexableItemStatisticsType',
+ 'UpdateDelegateType' => '\\jamesiarmes\\PhpEws\\Request\\UpdateDelegateType',
+ 'GetServiceConfigurationType' => '\\jamesiarmes\\PhpEws\\Request\\GetServiceConfigurationType',
+ 'AddImContactToGroup' => '\\jamesiarmes\\PhpEws\\Request\\AddImContactToGroup',
+ 'MarkAsJunkType' => '\\jamesiarmes\\PhpEws\\Request\\MarkAsJunkType',
+ 'UpdateItemType' => '\\jamesiarmes\\PhpEws\\Request\\UpdateItemType',
+ 'BaseDelegateType' => '\\jamesiarmes\\PhpEws\\Request\\BaseDelegateType',
+ 'MarkAllItemsAsRead' => '\\jamesiarmes\\PhpEws\\Request\\MarkAllItemsAsRead',
+ 'CopyItemType' => '\\jamesiarmes\\PhpEws\\Request\\CopyItemType',
+ 'SendItemType' => '\\jamesiarmes\\PhpEws\\Request\\SendItemType',
+ // Map for Response classes.
+ 'GetRoomsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetRoomsResponseMessageType',
+ 'SetUserOofSettingsResponse' => '\\jamesiarmes\\PhpEws\\Response\\SetUserOofSettingsResponse',
+ 'GetUserConfigurationResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetUserConfigurationResponseType',
+ 'UnsubscribeResponseType' => '\\jamesiarmes\\PhpEws\\Response\\UnsubscribeResponseType',
+ 'GetPhoneCallInformationResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetPhoneCallInformationResponseMessageType',
+ 'FindMessageTrackingReportResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\FindMessageTrackingReportResponseMessageType',
+ 'ServiceConfigurationResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ServiceConfigurationResponseMessageType',
+ 'GetSharingMetadataResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetSharingMetadataResponseMessageType',
+ 'GetFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetFolderResponseType',
+ 'MarkAllItemsAsReadResponseType' => '\\jamesiarmes\\PhpEws\\Response\\MarkAllItemsAsReadResponseType',
+ 'UpdateItemResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\UpdateItemResponseMessageType',
+ 'SubscribeResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\SubscribeResponseMessageType',
+ 'GetImItemsResponse' => '\\jamesiarmes\\PhpEws\\Response\\GetImItemsResponse',
+ 'ItemInfoResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ItemInfoResponseMessageType',
+ 'UploadItemsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\UploadItemsResponseMessageType',
+ 'GetRemindersResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetRemindersResponseMessageType',
+ 'AddNewTelUriContactToGroupResponse' => '\\jamesiarmes\\PhpEws\\Response\\AddNewTelUriContactToGroupResponse',
+ 'UpdateFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\UpdateFolderResponseType',
+ 'GetRoomListsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetRoomListsResponseMessageType',
+ 'ApplyConversationActionResponseType' => '\\jamesiarmes\\PhpEws\\Response\\ApplyConversationActionResponseType',
+ 'CreateFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CreateFolderResponseType',
+ 'GetClientAccessTokenResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetClientAccessTokenResponseMessageType',
+ 'GetHoldOnMailboxesResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetHoldOnMailboxesResponseMessageType',
+ 'SetImGroupResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\SetImGroupResponseMessageType',
+ 'MailTipsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\MailTipsResponseMessageType',
+ 'UninstallAppResponseType' => '\\jamesiarmes\\PhpEws\\Response\\UninstallAppResponseType',
+ 'SendNotificationResponseType' => '\\jamesiarmes\\PhpEws\\Response\\SendNotificationResponseType',
+ 'DisconnectPhoneCallResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\DisconnectPhoneCallResponseMessageType',
+ 'DeleteAttachmentResponseType' => '\\jamesiarmes\\PhpEws\\Response\\DeleteAttachmentResponseType',
+ 'UploadItemsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\UploadItemsResponseType',
+ 'PlayOnPhoneResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\PlayOnPhoneResponseMessageType',
+ 'GetPersonaResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetPersonaResponseMessageType',
+ 'GetConversationItemsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetConversationItemsResponseMessageType',
+ 'FindMailboxStatisticsByKeywordsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\FindMailboxStatisticsByKeywordsResponseType',
+ 'SyncFolderHierarchyResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\SyncFolderHierarchyResponseMessageType',
+ 'AddImContactToGroupResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\AddImContactToGroupResponseMessageType',
+ 'ResolveNamesResponseType' => '\\jamesiarmes\\PhpEws\\Response\\ResolveNamesResponseType',
+ 'MarkAsJunkResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\MarkAsJunkResponseMessageType',
+ 'GetConversationItemsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetConversationItemsResponseType',
+ 'MoveFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\MoveFolderResponseType',
+ 'AddImGroupResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\AddImGroupResponseMessageType',
+ 'ArchiveItemResponse' => '\\jamesiarmes\\PhpEws\\Response\\ArchiveItemResponse',
+ 'GetPasswordExpirationDateResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetPasswordExpirationDateResponseMessageType',
+ 'RemoveImContactFromGroupResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\RemoveImContactFromGroupResponseMessageType',
+ 'FindFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\FindFolderResponseType',
+ 'GetServerTimeZonesResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetServerTimeZonesResponseMessageType',
+ 'RemoveContactFromImListResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\RemoveContactFromImListResponseMessageType',
+ 'ResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ResponseMessageType',
+ 'UpdateInboxRulesResponseType' => '\\jamesiarmes\\PhpEws\\Response\\UpdateInboxRulesResponseType',
+ 'UpdateUserConfigurationResponseType' => '\\jamesiarmes\\PhpEws\\Response\\UpdateUserConfigurationResponseType',
+ 'GetServiceConfigurationResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetServiceConfigurationResponseMessageType',
+ 'CreateUserConfigurationResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CreateUserConfigurationResponseType',
+ 'SearchMailboxesResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\SearchMailboxesResponseMessageType',
+ 'FindMailboxStatisticsByKeywordsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\FindMailboxStatisticsByKeywordsResponseMessageType',
+ 'GetUserOofSettingsResponse' => '\\jamesiarmes\\PhpEws\\Response\\GetUserOofSettingsResponse',
+ 'GetItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetItemResponseType',
+ 'SyncFolderItemsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\SyncFolderItemsResponseType',
+ 'RemoveDelegateResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\RemoveDelegateResponseMessageType',
+ 'GetInboxRulesResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetInboxRulesResponseType',
+ 'DeleteFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\DeleteFolderResponseType',
+ 'AddDistributionGroupToImListResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\AddDistributionGroupToImListResponseMessageType',
+ 'BaseResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\BaseResponseMessageType',
+ 'CopyItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CopyItemResponseType',
+ 'SetHoldOnMailboxesResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\SetHoldOnMailboxesResponseMessageType',
+ 'GetNonIndexableItemStatisticsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetNonIndexableItemStatisticsResponseMessageType',
+ 'DisableAppResponseType' => '\\jamesiarmes\\PhpEws\\Response\\DisableAppResponseType',
+ 'RefreshSharingFolderResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\RefreshSharingFolderResponseMessageType',
+ 'FindConversationResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\FindConversationResponseMessageType',
+ 'SendItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\SendItemResponseType',
+ 'RemoveDistributionGroupFromImListResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\RemoveDistributionGroupFromImListResponseMessageType',
+ 'GetDiscoverySearchConfigurationResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetDiscoverySearchConfigurationResponseMessageType',
+ 'GetEventsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetEventsResponseType',
+ 'ConvertIdResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ConvertIdResponseMessageType',
+ 'FindPeopleResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\FindPeopleResponseMessageType',
+ 'FindItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\FindItemResponseType',
+ 'GetAppManifestsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetAppManifestsResponseType',
+ 'CreateAttachmentResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CreateAttachmentResponseType',
+ 'PerformReminderActionResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\PerformReminderActionResponseMessageType',
+ 'SendNotificationResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\SendNotificationResponseMessageType',
+ 'FindItemResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\FindItemResponseMessageType',
+ 'GetAttachmentResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetAttachmentResponseType',
+ 'ExportItemsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\ExportItemsResponseType',
+ 'BaseDelegateResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\BaseDelegateResponseMessageType',
+ 'GetStreamingEventsResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetStreamingEventsResponseType',
+ 'GetStreamingEventsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetStreamingEventsResponseMessageType',
+ 'MoveItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\MoveItemResponseType',
+ 'GetUserRetentionPolicyTagsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetUserRetentionPolicyTagsResponseMessageType',
+ 'SyncFolderItemsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\SyncFolderItemsResponseMessageType',
+ 'DeleteItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\DeleteItemResponseType',
+ 'ConvertIdResponseType' => '\\jamesiarmes\\PhpEws\\Response\\ConvertIdResponseType',
+ 'ExpandDLResponseType' => '\\jamesiarmes\\PhpEws\\Response\\ExpandDLResponseType',
+ 'ExpandDLResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ExpandDLResponseMessageType',
+ 'GetDelegateResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetDelegateResponseMessageType',
+ 'GetClientAccessTokenResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetClientAccessTokenResponseType',
+ 'MarkAsJunkResponseType' => '\\jamesiarmes\\PhpEws\\Response\\MarkAsJunkResponseType',
+ 'CreateManagedFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CreateManagedFolderResponseType',
+ 'InstallAppResponseType' => '\\jamesiarmes\\PhpEws\\Response\\InstallAppResponseType',
+ 'FolderInfoResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\FolderInfoResponseMessageType',
+ 'GetMessageTrackingReportResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetMessageTrackingReportResponseMessageType',
+ 'AttachmentInfoResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\AttachmentInfoResponseMessageType',
+ 'SubscribeResponseType' => '\\jamesiarmes\\PhpEws\\Response\\SubscribeResponseType',
+ 'GetSharingFolderResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetSharingFolderResponseMessageType',
+ 'DelegateUserResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\DelegateUserResponseMessageType',
+ 'UpdateItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\UpdateItemResponseType',
+ 'CreateFolderPathResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CreateFolderPathResponseType',
+ 'AddNewImContactToGroupResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\AddNewImContactToGroupResponseMessageType',
+ 'GetServerTimeZonesResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetServerTimeZonesResponseType',
+ 'ExportItemsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ExportItemsResponseMessageType',
+ 'GetMailTipsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetMailTipsResponseMessageType',
+ 'GetUserConfigurationResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetUserConfigurationResponseMessageType',
+ 'GetUserPhotoResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetUserPhotoResponseMessageType',
+ 'RemoveImGroupResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\RemoveImGroupResponseMessageType',
+ 'SearchMailboxesResponseType' => '\\jamesiarmes\\PhpEws\\Response\\SearchMailboxesResponseType',
+ 'ResolveNamesResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ResolveNamesResponseMessageType',
+ 'DeleteUserConfigurationResponseType' => '\\jamesiarmes\\PhpEws\\Response\\DeleteUserConfigurationResponseType',
+ 'GetUserPhotoResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetUserPhotoResponseType',
+ 'SyncFolderHierarchyResponseType' => '\\jamesiarmes\\PhpEws\\Response\\SyncFolderHierarchyResponseType',
+ 'GetUserAvailabilityResponseType' => '\\jamesiarmes\\PhpEws\\Response\\GetUserAvailabilityResponseType',
+ 'EmptyFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\EmptyFolderResponseType',
+ 'FindFolderResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\FindFolderResponseMessageType',
+ 'DeleteAttachmentResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\DeleteAttachmentResponseMessageType',
+ 'GetAppMarketplaceUrlResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetAppMarketplaceUrlResponseMessageType',
+ 'CopyFolderResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CopyFolderResponseType',
+ 'UpdateDelegateResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\UpdateDelegateResponseMessageType',
+ 'CreateItemResponseType' => '\\jamesiarmes\\PhpEws\\Response\\CreateItemResponseType',
+ 'ApplyConversationActionResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\ApplyConversationActionResponseMessageType',
+ 'GetEventsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetEventsResponseMessageType',
+ 'AddDelegateResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\AddDelegateResponseMessageType',
+ 'GetImItemListResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetImItemListResponseMessageType',
+ 'GetSearchableMailboxesResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetSearchableMailboxesResponseMessageType',
+ 'GetNonIndexableItemDetailsResponseMessageType' => '\\jamesiarmes\\PhpEws\\Response\\GetNonIndexableItemDetailsResponseMessageType',
+ // Map for Type classes.
+ 'ExcludesType' => '\\jamesiarmes\\PhpEws\\Type\\ExcludesType',
+ 'IsNotEqualToType' => '\\jamesiarmes\\PhpEws\\Type\\IsNotEqualToType',
+ 'MessageTrackingReportType' => '\\jamesiarmes\\PhpEws\\Type\\MessageTrackingReportType',
+ 'PhysicalAddressDictionaryType' => '\\jamesiarmes\\PhpEws\\Type\\PhysicalAddressDictionaryType',
+ 'IntervalRecurrencePatternBaseType' => '\\jamesiarmes\\PhpEws\\Type\\IntervalRecurrencePatternBaseType',
+ 'BaseEmailAddressType' => '\\jamesiarmes\\PhpEws\\Type\\BaseEmailAddressType',
+ 'FindMessageTrackingSearchResultType' => '\\jamesiarmes\\PhpEws\\Type\\FindMessageTrackingSearchResultType',
+ 'ProtectionRuleSenderDepartmentsType' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRuleSenderDepartmentsType',
+ 'SeekToConditionPageViewType' => '\\jamesiarmes\\PhpEws\\Type\\SeekToConditionPageViewType',
+ 'SmtpDomain' => '\\jamesiarmes\\PhpEws\\Type\\SmtpDomain',
+ 'EmailAddressDictionaryType' => '\\jamesiarmes\\PhpEws\\Type\\EmailAddressDictionaryType',
+ 'ItemAttachmentType' => '\\jamesiarmes\\PhpEws\\Type\\ItemAttachmentType',
+ 'MovedCopiedEventType' => '\\jamesiarmes\\PhpEws\\Type\\MovedCopiedEventType',
+ 'FindFolderParentType' => '\\jamesiarmes\\PhpEws\\Type\\FindFolderParentType',
+ 'FileAttachmentType' => '\\jamesiarmes\\PhpEws\\Type\\FileAttachmentType',
+ 'ItemChangeType' => '\\jamesiarmes\\PhpEws\\Type\\ItemChangeType',
+ 'CreateRuleOperationType' => '\\jamesiarmes\\PhpEws\\Type\\CreateRuleOperationType',
+ 'StringAttributedValueType' => '\\jamesiarmes\\PhpEws\\Type\\StringAttributedValueType',
+ 'ContactsFolderType' => '\\jamesiarmes\\PhpEws\\Type\\ContactsFolderType',
+ 'BaseGroupByType' => '\\jamesiarmes\\PhpEws\\Type\\BaseGroupByType',
+ 'ConversationShape' => '\\jamesiarmes\\PhpEws\\Type\\ConversationShape',
+ 'ReminderType' => '\\jamesiarmes\\PhpEws\\Type\\ReminderType',
+ 'ContactItemType' => '\\jamesiarmes\\PhpEws\\Type\\ContactItemType',
+ 'OccurrenceInfoType' => '\\jamesiarmes\\PhpEws\\Type\\OccurrenceInfoType',
+ 'TargetFolderIdType' => '\\jamesiarmes\\PhpEws\\Type\\TargetFolderIdType',
+ 'BaseFolderType' => '\\jamesiarmes\\PhpEws\\Type\\BaseFolderType',
+ 'DailyRegeneratingPatternType' => '\\jamesiarmes\\PhpEws\\Type\\DailyRegeneratingPatternType',
+ 'RulePredicateSizeRangeType' => '\\jamesiarmes\\PhpEws\\Type\\RulePredicateSizeRangeType',
+ 'AttachmentType' => '\\jamesiarmes\\PhpEws\\Type\\AttachmentType',
+ 'SearchParametersType' => '\\jamesiarmes\\PhpEws\\Type\\SearchParametersType',
+ 'MailboxData' => '\\jamesiarmes\\PhpEws\\Type\\MailboxData',
+ 'ImAddressDictionaryType' => '\\jamesiarmes\\PhpEws\\Type\\ImAddressDictionaryType',
+ 'PreviewItemMailboxType' => '\\jamesiarmes\\PhpEws\\Type\\PreviewItemMailboxType',
+ 'PathToIndexedFieldType' => '\\jamesiarmes\\PhpEws\\Type\\PathToIndexedFieldType',
+ 'AlternatePublicFolderItemIdType' => '\\jamesiarmes\\PhpEws\\Type\\AlternatePublicFolderItemIdType',
+ 'AttendeeConflictData' => '\\jamesiarmes\\PhpEws\\Type\\AttendeeConflictData',
+ 'CalendarFolderType' => '\\jamesiarmes\\PhpEws\\Type\\CalendarFolderType',
+ 'RecurrenceType' => '\\jamesiarmes\\PhpEws\\Type\\RecurrenceType',
+ 'UserConfigurationDictionaryEntryType' => '\\jamesiarmes\\PhpEws\\Type\\UserConfigurationDictionaryEntryType',
+ 'ItemType' => '\\jamesiarmes\\PhpEws\\Type\\ItemType',
+ 'TimeZoneDefinitionType' => '\\jamesiarmes\\PhpEws\\Type\\TimeZoneDefinitionType',
+ 'SingleRecipientType' => '\\jamesiarmes\\PhpEws\\Type\\SingleRecipientType',
+ 'NonIndexableItemStatisticType' => '\\jamesiarmes\\PhpEws\\Type\\NonIndexableItemStatisticType',
+ 'IsGreaterThanOrEqualToType' => '\\jamesiarmes\\PhpEws\\Type\\IsGreaterThanOrEqualToType',
+ 'BaseItemIdType' => '\\jamesiarmes\\PhpEws\\Type\\BaseItemIdType',
+ 'IndexedPageViewType' => '\\jamesiarmes\\PhpEws\\Type\\IndexedPageViewType',
+ 'WeeklyRecurrencePatternType' => '\\jamesiarmes\\PhpEws\\Type\\WeeklyRecurrencePatternType',
+ 'ServiceConfiguration' => '\\jamesiarmes\\PhpEws\\Type\\ServiceConfiguration',
+ 'CompleteNameType' => '\\jamesiarmes\\PhpEws\\Type\\CompleteNameType',
+ 'MailboxHoldResultType' => '\\jamesiarmes\\PhpEws\\Type\\MailboxHoldResultType',
+ 'IsLessThanType' => '\\jamesiarmes\\PhpEws\\Type\\IsLessThanType',
+ 'Suggestion' => '\\jamesiarmes\\PhpEws\\Type\\Suggestion',
+ 'SidAndAttributesType' => '\\jamesiarmes\\PhpEws\\Type\\SidAndAttributesType',
+ 'ImAddressDictionaryEntryType' => '\\jamesiarmes\\PhpEws\\Type\\ImAddressDictionaryEntryType',
+ 'RecurringDateTransitionType' => '\\jamesiarmes\\PhpEws\\Type\\RecurringDateTransitionType',
+ 'MailTipsServiceConfiguration' => '\\jamesiarmes\\PhpEws\\Type\\MailTipsServiceConfiguration',
+ 'UserConfigurationDictionaryType' => '\\jamesiarmes\\PhpEws\\Type\\UserConfigurationDictionaryType',
+ 'AttendeeType' => '\\jamesiarmes\\PhpEws\\Type\\AttendeeType',
+ 'ReplyToItemType' => '\\jamesiarmes\\PhpEws\\Type\\ReplyToItemType',
+ 'KeywordStatisticsSearchResultType' => '\\jamesiarmes\\PhpEws\\Type\\KeywordStatisticsSearchResultType',
+ 'AlternatePublicFolderIdType' => '\\jamesiarmes\\PhpEws\\Type\\AlternatePublicFolderIdType',
+ 'TimeZoneContextType' => '\\jamesiarmes\\PhpEws\\Type\\TimeZoneContextType',
+ 'BaseFolderIdType' => '\\jamesiarmes\\PhpEws\\Type\\BaseFolderIdType',
+ 'TaskType' => '\\jamesiarmes\\PhpEws\\Type\\TaskType',
+ 'ContextPropertyType' => '\\jamesiarmes\\PhpEws\\Type\\ContextPropertyType',
+ 'PersonaAttributionType' => '\\jamesiarmes\\PhpEws\\Type\\PersonaAttributionType',
+ 'TentativelyAcceptItemType' => '\\jamesiarmes\\PhpEws\\Type\\TentativelyAcceptItemType',
+ 'AcceptSharingInvitationType' => '\\jamesiarmes\\PhpEws\\Type\\AcceptSharingInvitationType',
+ 'ConversationResponseType' => '\\jamesiarmes\\PhpEws\\Type\\ConversationResponseType',
+ 'ResolutionType' => '\\jamesiarmes\\PhpEws\\Type\\ResolutionType',
+ 'PeriodType' => '\\jamesiarmes\\PhpEws\\Type\\PeriodType',
+ 'WorkingHours' => '\\jamesiarmes\\PhpEws\\Type\\WorkingHours',
+ 'SetItemFieldType' => '\\jamesiarmes\\PhpEws\\Type\\SetItemFieldType',
+ 'ConflictResultsType' => '\\jamesiarmes\\PhpEws\\Type\\ConflictResultsType',
+ 'PreviewItemResponseShapeType' => '\\jamesiarmes\\PhpEws\\Type\\PreviewItemResponseShapeType',
+ 'AppendToItemFieldType' => '\\jamesiarmes\\PhpEws\\Type\\AppendToItemFieldType',
+ 'RuleActionsType' => '\\jamesiarmes\\PhpEws\\Type\\RuleActionsType',
+ 'FieldURIOrConstantType' => '\\jamesiarmes\\PhpEws\\Type\\FieldURIOrConstantType',
+ 'IndividualAttendeeConflictData' => '\\jamesiarmes\\PhpEws\\Type\\IndividualAttendeeConflictData',
+ 'ConversationActionType' => '\\jamesiarmes\\PhpEws\\Type\\ConversationActionType',
+ 'UserConfigurationType' => '\\jamesiarmes\\PhpEws\\Type\\UserConfigurationType',
+ 'RecurringDayTransitionType' => '\\jamesiarmes\\PhpEws\\Type\\RecurringDayTransitionType',
+ 'FolderChangeType' => '\\jamesiarmes\\PhpEws\\Type\\FolderChangeType',
+ 'RuleOperationType' => '\\jamesiarmes\\PhpEws\\Type\\RuleOperationType',
+ 'DeleteRuleOperationType' => '\\jamesiarmes\\PhpEws\\Type\\DeleteRuleOperationType',
+ 'ConversationNodeType' => '\\jamesiarmes\\PhpEws\\Type\\ConversationNodeType',
+ 'PathToUnindexedFieldType' => '\\jamesiarmes\\PhpEws\\Type\\PathToUnindexedFieldType',
+ 'SearchPreviewItemType' => '\\jamesiarmes\\PhpEws\\Type\\SearchPreviewItemType',
+ 'EncryptedSharedFolderDataType' => '\\jamesiarmes\\PhpEws\\Type\\EncryptedSharedFolderDataType',
+ 'SerializableTimeZoneTime' => '\\jamesiarmes\\PhpEws\\Type\\SerializableTimeZoneTime',
+ 'BodyContentAttributedValueType' => '\\jamesiarmes\\PhpEws\\Type\\BodyContentAttributedValueType',
+ 'UserConfigurationDictionaryObjectType' => '\\jamesiarmes\\PhpEws\\Type\\UserConfigurationDictionaryObjectType',
+ 'AttachmentResponseShapeType' => '\\jamesiarmes\\PhpEws\\Type\\AttachmentResponseShapeType',
+ 'ItemResponseShapeType' => '\\jamesiarmes\\PhpEws\\Type\\ItemResponseShapeType',
+ 'SearchMailboxesResultType' => '\\jamesiarmes\\PhpEws\\Type\\SearchMailboxesResultType',
+ 'PersonaResponseShapeType' => '\\jamesiarmes\\PhpEws\\Type\\PersonaResponseShapeType',
+ 'TwoOperandExpressionType' => '\\jamesiarmes\\PhpEws\\Type\\TwoOperandExpressionType',
+ 'TaskRecurrenceType' => '\\jamesiarmes\\PhpEws\\Type\\TaskRecurrenceType',
+ 'MessageType' => '\\jamesiarmes\\PhpEws\\Type\\MessageType',
+ 'PostItemType' => '\\jamesiarmes\\PhpEws\\Type\\PostItemType',
+ 'DeclineItemType' => '\\jamesiarmes\\PhpEws\\Type\\DeclineItemType',
+ 'NonIndexableItemDetailResultType' => '\\jamesiarmes\\PhpEws\\Type\\NonIndexableItemDetailResultType',
+ 'ReminderItemActionType' => '\\jamesiarmes\\PhpEws\\Type\\ReminderItemActionType',
+ 'SyncFolderItemsChangesType' => '\\jamesiarmes\\PhpEws\\Type\\SyncFolderItemsChangesType',
+ 'OutOfOfficeMailTip' => '\\jamesiarmes\\PhpEws\\Type\\OutOfOfficeMailTip',
+ 'ConnectingSIDType' => '\\jamesiarmes\\PhpEws\\Type\\ConnectingSIDType',
+ 'MailboxHoldStatusType' => '\\jamesiarmes\\PhpEws\\Type\\MailboxHoldStatusType',
+ 'RootItemIdType' => '\\jamesiarmes\\PhpEws\\Type\\RootItemIdType',
+ 'SerializableTimeZone' => '\\jamesiarmes\\PhpEws\\Type\\SerializableTimeZone',
+ 'PersonaType' => '\\jamesiarmes\\PhpEws\\Type\\PersonaType',
+ 'ReplyAllToItemType' => '\\jamesiarmes\\PhpEws\\Type\\ReplyAllToItemType',
+ 'InternetHeaderType' => '\\jamesiarmes\\PhpEws\\Type\\InternetHeaderType',
+ 'ModifiedEventType' => '\\jamesiarmes\\PhpEws\\Type\\ModifiedEventType',
+ 'GroupAttendeeConflictData' => '\\jamesiarmes\\PhpEws\\Type\\GroupAttendeeConflictData',
+ 'EffectiveRightsType' => '\\jamesiarmes\\PhpEws\\Type\\EffectiveRightsType',
+ 'WellKnownResponseObjectType' => '\\jamesiarmes\\PhpEws\\Type\\WellKnownResponseObjectType',
+ 'SyncFolderItemsReadFlagType' => '\\jamesiarmes\\PhpEws\\Type\\SyncFolderItemsReadFlagType',
+ 'DeleteItemFieldType' => '\\jamesiarmes\\PhpEws\\Type\\DeleteItemFieldType',
+ 'BodyContentType' => '\\jamesiarmes\\PhpEws\\Type\\BodyContentType',
+ 'InstalledAppType' => '\\jamesiarmes\\PhpEws\\Type\\InstalledAppType',
+ 'ProposeNewTimeType' => '\\jamesiarmes\\PhpEws\\Type\\ProposeNewTimeType',
+ 'PhoneNumberDictionaryType' => '\\jamesiarmes\\PhpEws\\Type\\PhoneNumberDictionaryType',
+ 'TooBigGroupAttendeeConflictData' => '\\jamesiarmes\\PhpEws\\Type\\TooBigGroupAttendeeConflictData',
+ 'SuggestionsViewOptionsType' => '\\jamesiarmes\\PhpEws\\Type\\SuggestionsViewOptionsType',
+ 'PermissionSetType' => '\\jamesiarmes\\PhpEws\\Type\\PermissionSetType',
+ 'CalendarEvent' => '\\jamesiarmes\\PhpEws\\Type\\CalendarEvent',
+ 'ExistsType' => '\\jamesiarmes\\PhpEws\\Type\\ExistsType',
+ 'ProtectionRuleArgumentType' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRuleArgumentType',
+ 'ChangeDescriptionType' => '\\jamesiarmes\\PhpEws\\Type\\ChangeDescriptionType',
+ 'FolderIdType' => '\\jamesiarmes\\PhpEws\\Type\\FolderIdType',
+ 'DeletedOccurrenceInfoType' => '\\jamesiarmes\\PhpEws\\Type\\DeletedOccurrenceInfoType',
+ 'SuggestionDayResult' => '\\jamesiarmes\\PhpEws\\Type\\SuggestionDayResult',
+ 'GroupByType' => '\\jamesiarmes\\PhpEws\\Type\\GroupByType',
+ 'UnifiedMessageServiceConfiguration' => '\\jamesiarmes\\PhpEws\\Type\\UnifiedMessageServiceConfiguration',
+ 'ContactsViewType' => '\\jamesiarmes\\PhpEws\\Type\\ContactsViewType',
+ 'RulePredicatesType' => '\\jamesiarmes\\PhpEws\\Type\\RulePredicatesType',
+ 'TrackingPropertyType' => '\\jamesiarmes\\PhpEws\\Type\\TrackingPropertyType',
+ 'ClientAccessTokenType' => '\\jamesiarmes\\PhpEws\\Type\\ClientAccessTokenType',
+ 'MeetingResponseMessageType' => '\\jamesiarmes\\PhpEws\\Type\\MeetingResponseMessageType',
+ 'BaseNotificationEventType' => '\\jamesiarmes\\PhpEws\\Type\\BaseNotificationEventType',
+ 'UserOofSettings' => '\\jamesiarmes\\PhpEws\\Type\\UserOofSettings',
+ 'PhoneCallInformationType' => '\\jamesiarmes\\PhpEws\\Type\\PhoneCallInformationType',
+ 'RemoveItemType' => '\\jamesiarmes\\PhpEws\\Type\\RemoveItemType',
+ 'RuleType' => '\\jamesiarmes\\PhpEws\\Type\\RuleType',
+ 'SyncFolderHierarchyDeleteType' => '\\jamesiarmes\\PhpEws\\Type\\SyncFolderHierarchyDeleteType',
+ 'ResponseObjectType' => '\\jamesiarmes\\PhpEws\\Type\\ResponseObjectType',
+ 'DistinguishedGroupByType' => '\\jamesiarmes\\PhpEws\\Type\\DistinguishedGroupByType',
+ 'SyncFolderHierarchyCreateOrUpdateType' => '\\jamesiarmes\\PhpEws\\Type\\SyncFolderHierarchyCreateOrUpdateType',
+ 'CalendarPermissionSetType' => '\\jamesiarmes\\PhpEws\\Type\\CalendarPermissionSetType',
+ 'RuleValidationErrorType' => '\\jamesiarmes\\PhpEws\\Type\\RuleValidationErrorType',
+ 'MailboxQueryType' => '\\jamesiarmes\\PhpEws\\Type\\MailboxQueryType',
+ 'UploadItemType' => '\\jamesiarmes\\PhpEws\\Type\\UploadItemType',
+ 'BodyType' => '\\jamesiarmes\\PhpEws\\Type\\BodyType',
+ 'SyncFolderItemsDeleteType' => '\\jamesiarmes\\PhpEws\\Type\\SyncFolderItemsDeleteType',
+ 'BasePermissionType' => '\\jamesiarmes\\PhpEws\\Type\\BasePermissionType',
+ 'WeeklyRegeneratingPatternType' => '\\jamesiarmes\\PhpEws\\Type\\WeeklyRegeneratingPatternType',
+ 'MeetingMessageType' => '\\jamesiarmes\\PhpEws\\Type\\MeetingMessageType',
+ 'PathToExtendedFieldType' => '\\jamesiarmes\\PhpEws\\Type\\PathToExtendedFieldType',
+ 'SearchableMailboxType' => '\\jamesiarmes\\PhpEws\\Type\\SearchableMailboxType',
+ 'AttachmentIdType' => '\\jamesiarmes\\PhpEws\\Type\\AttachmentIdType',
+ 'ExtendedAttributeType' => '\\jamesiarmes\\PhpEws\\Type\\ExtendedAttributeType',
+ 'ForwardItemType' => '\\jamesiarmes\\PhpEws\\Type\\ForwardItemType',
+ 'RecipientTrackingEventType' => '\\jamesiarmes\\PhpEws\\Type\\RecipientTrackingEventType',
+ 'ResponseObjectCoreType' => '\\jamesiarmes\\PhpEws\\Type\\ResponseObjectCoreType',
+ 'ImGroupType' => '\\jamesiarmes\\PhpEws\\Type\\ImGroupType',
+ 'ExcludesValueType' => '\\jamesiarmes\\PhpEws\\Type\\ExcludesValueType',
+ 'SmtpDomainList' => '\\jamesiarmes\\PhpEws\\Type\\SmtpDomainList',
+ 'UserIdType' => '\\jamesiarmes\\PhpEws\\Type\\UserIdType',
+ 'ProtectionRuleConditionType' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRuleConditionType',
+ 'ReferenceItemResponseType' => '\\jamesiarmes\\PhpEws\\Type\\ReferenceItemResponseType',
+ 'RecurrencePatternBaseType' => '\\jamesiarmes\\PhpEws\\Type\\RecurrencePatternBaseType',
+ 'FolderResponseShapeType' => '\\jamesiarmes\\PhpEws\\Type\\FolderResponseShapeType',
+ 'NonIndexableItemDetailType' => '\\jamesiarmes\\PhpEws\\Type\\NonIndexableItemDetailType',
+ 'ManagedFolderInformationType' => '\\jamesiarmes\\PhpEws\\Type\\ManagedFolderInformationType',
+ 'OpenAsAdminOrSystemServiceType' => '\\jamesiarmes\\PhpEws\\Type\\OpenAsAdminOrSystemServiceType',
+ 'Duration' => '\\jamesiarmes\\PhpEws\\Type\\Duration',
+ 'RelativeYearlyRecurrencePatternType' => '\\jamesiarmes\\PhpEws\\Type\\RelativeYearlyRecurrencePatternType',
+ 'BasePagingType' => '\\jamesiarmes\\PhpEws\\Type\\BasePagingType',
+ 'TimeChangeType' => '\\jamesiarmes\\PhpEws\\Type\\TimeChangeType',
+ 'RestrictionType' => '\\jamesiarmes\\PhpEws\\Type\\RestrictionType',
+ 'SearchFolderType' => '\\jamesiarmes\\PhpEws\\Type\\SearchFolderType',
+ 'EmailAddressType' => '\\jamesiarmes\\PhpEws\\Type\\EmailAddressType',
+ 'FolderChangeDescriptionType' => '\\jamesiarmes\\PhpEws\\Type\\FolderChangeDescriptionType',
+ 'ProtectionRuleType' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRuleType',
+ 'RoomType' => '\\jamesiarmes\\PhpEws\\Type\\RoomType',
+ 'ServerVersionInfo' => '\\jamesiarmes\\PhpEws\\Type\\ServerVersionInfo',
+ 'OccurrencesRangeType' => '\\jamesiarmes\\PhpEws\\Type\\OccurrencesRangeType',
+ 'StreamingSubscriptionRequest' => '\\jamesiarmes\\PhpEws\\Type\\StreamingSubscriptionRequest',
+ 'FreeBusyViewOptionsType' => '\\jamesiarmes\\PhpEws\\Type\\FreeBusyViewOptionsType',
+ 'CalendarItemType' => '\\jamesiarmes\\PhpEws\\Type\\CalendarItemType',
+ 'PhoneNumberDictionaryEntryType' => '\\jamesiarmes\\PhpEws\\Type\\PhoneNumberDictionaryEntryType',
+ 'ProtectionRulesServiceConfiguration' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRulesServiceConfiguration',
+ 'UserMailboxType' => '\\jamesiarmes\\PhpEws\\Type\\UserMailboxType',
+ 'FieldOrderType' => '\\jamesiarmes\\PhpEws\\Type\\FieldOrderType',
+ 'CalendarPermissionType' => '\\jamesiarmes\\PhpEws\\Type\\CalendarPermissionType',
+ 'MeetingRequestMessageType' => '\\jamesiarmes\\PhpEws\\Type\\MeetingRequestMessageType',
+ 'RecurringMasterItemIdRanges' => '\\jamesiarmes\\PhpEws\\Type\\RecurringMasterItemIdRanges',
+ 'RecurringTimeTransitionType' => '\\jamesiarmes\\PhpEws\\Type\\RecurringTimeTransitionType',
+ 'AbsoluteDateTransitionType' => '\\jamesiarmes\\PhpEws\\Type\\AbsoluteDateTransitionType',
+ 'TransitionType' => '\\jamesiarmes\\PhpEws\\Type\\TransitionType',
+ 'NoEndRecurrenceRangeType' => '\\jamesiarmes\\PhpEws\\Type\\NoEndRecurrenceRangeType',
+ 'ClientAccessTokenRequestType' => '\\jamesiarmes\\PhpEws\\Type\\ClientAccessTokenRequestType',
+ 'PersonaPostalAddressType' => '\\jamesiarmes\\PhpEws\\Type\\PersonaPostalAddressType',
+ 'AbsoluteMonthlyRecurrencePatternType' => '\\jamesiarmes\\PhpEws\\Type\\AbsoluteMonthlyRecurrencePatternType',
+ 'ImItemListType' => '\\jamesiarmes\\PhpEws\\Type\\ImItemListType',
+ 'TransitionTargetType' => '\\jamesiarmes\\PhpEws\\Type\\TransitionTargetType',
+ 'BaseObjectChangedEventType' => '\\jamesiarmes\\PhpEws\\Type\\BaseObjectChangedEventType',
+ 'FreeBusyView' => '\\jamesiarmes\\PhpEws\\Type\\FreeBusyView',
+ 'MemberType' => '\\jamesiarmes\\PhpEws\\Type\\MemberType',
+ 'DistinguishedFolderIdType' => '\\jamesiarmes\\PhpEws\\Type\\DistinguishedFolderIdType',
+ 'ConstantValueType' => '\\jamesiarmes\\PhpEws\\Type\\ConstantValueType',
+ 'String' => '\\jamesiarmes\\PhpEws\\Type\\StringType',
+ 'PrivateCatalogAddInsType' => '\\jamesiarmes\\PhpEws\\Type\\PrivateCatalogAddInsType',
+ 'PostalAddressAttributedValueType' => '\\jamesiarmes\\PhpEws\\Type\\PostalAddressAttributedValueType',
+ 'MembersListType' => '\\jamesiarmes\\PhpEws\\Type\\MembersListType',
+ 'RelativeMonthlyRecurrencePatternType' => '\\jamesiarmes\\PhpEws\\Type\\RelativeMonthlyRecurrencePatternType',
+ 'AlternateIdType' => '\\jamesiarmes\\PhpEws\\Type\\AlternateIdType',
+ 'QueryStringType' => '\\jamesiarmes\\PhpEws\\Type\\QueryStringType',
+ 'MultipleOperandBooleanExpressionType' => '\\jamesiarmes\\PhpEws\\Type\\MultipleOperandBooleanExpressionType',
+ 'PersonaPhoneNumberType' => '\\jamesiarmes\\PhpEws\\Type\\PersonaPhoneNumberType',
+ 'PhoneNumberAttributedValueType' => '\\jamesiarmes\\PhpEws\\Type\\PhoneNumberAttributedValueType',
+ 'MimeContentType' => '\\jamesiarmes\\PhpEws\\Type\\MimeContentType',
+ 'PullSubscriptionRequestType' => '\\jamesiarmes\\PhpEws\\Type\\PullSubscriptionRequestType',
+ 'SendNotificationResultType' => '\\jamesiarmes\\PhpEws\\Type\\SendNotificationResultType',
+ 'UserConfigurationNameType' => '\\jamesiarmes\\PhpEws\\Type\\UserConfigurationNameType',
+ 'UnknownAttendeeConflictData' => '\\jamesiarmes\\PhpEws\\Type\\UnknownAttendeeConflictData',
+ 'ContainsExpressionType' => '\\jamesiarmes\\PhpEws\\Type\\ContainsExpressionType',
+ 'StringArrayAttributedValueType' => '\\jamesiarmes\\PhpEws\\Type\\StringArrayAttributedValueType',
+ 'SetFolderFieldType' => '\\jamesiarmes\\PhpEws\\Type\\SetFolderFieldType',
+ 'RecurrenceRangeBaseType' => '\\jamesiarmes\\PhpEws\\Type\\RecurrenceRangeBaseType',
+ 'ReplyBody' => '\\jamesiarmes\\PhpEws\\Type\\ReplyBody',
+ 'MeetingCancellationMessageType' => '\\jamesiarmes\\PhpEws\\Type\\MeetingCancellationMessageType',
+ 'EmailAddressDictionaryEntryType' => '\\jamesiarmes\\PhpEws\\Type\\EmailAddressDictionaryEntryType',
+ 'PostReplyItemBaseType' => '\\jamesiarmes\\PhpEws\\Type\\PostReplyItemBaseType',
+ 'ExtendedPropertyType' => '\\jamesiarmes\\PhpEws\\Type\\ExtendedPropertyType',
+ 'AbsoluteYearlyRecurrencePatternType' => '\\jamesiarmes\\PhpEws\\Type\\AbsoluteYearlyRecurrencePatternType',
+ 'DistributionListType' => '\\jamesiarmes\\PhpEws\\Type\\DistributionListType',
+ 'FolderType' => '\\jamesiarmes\\PhpEws\\Type\\FolderType',
+ 'SmartResponseBaseType' => '\\jamesiarmes\\PhpEws\\Type\\SmartResponseBaseType',
+ 'EmailAddressAttributedValueType' => '\\jamesiarmes\\PhpEws\\Type\\EmailAddressAttributedValueType',
+ 'InvalidRecipientType' => '\\jamesiarmes\\PhpEws\\Type\\InvalidRecipientType',
+ 'ProtectionRuleAndType' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRuleAndType',
+ 'RetentionPolicyTagType' => '\\jamesiarmes\\PhpEws\\Type\\RetentionPolicyTagType',
+ 'PermissionType' => '\\jamesiarmes\\PhpEws\\Type\\PermissionType',
+ 'AcceptItemType' => '\\jamesiarmes\\PhpEws\\Type\\AcceptItemType',
+ 'SearchExpressionType' => '\\jamesiarmes\\PhpEws\\Type\\SearchExpressionType',
+ 'TasksFolderType' => '\\jamesiarmes\\PhpEws\\Type\\TasksFolderType',
+ 'AppendToFolderFieldType' => '\\jamesiarmes\\PhpEws\\Type\\AppendToFolderFieldType',
+ 'TimeZoneType' => '\\jamesiarmes\\PhpEws\\Type\\TimeZoneType',
+ 'NotificationType' => '\\jamesiarmes\\PhpEws\\Type\\NotificationType',
+ 'ExtendedPropertyAttributedValueType' => '\\jamesiarmes\\PhpEws\\Type\\ExtendedPropertyAttributedValueType',
+ 'PhoneCallIdType' => '\\jamesiarmes\\PhpEws\\Type\\PhoneCallIdType',
+ 'RegeneratingPatternBaseType' => '\\jamesiarmes\\PhpEws\\Type\\RegeneratingPatternBaseType',
+ 'OrType' => '\\jamesiarmes\\PhpEws\\Type\\OrType',
+ 'MailboxSearchScopeType' => '\\jamesiarmes\\PhpEws\\Type\\MailboxSearchScopeType',
+ 'ProtectionRuleRecipientIsType' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRuleRecipientIsType',
+ 'ExchangeImpersonationType' => '\\jamesiarmes\\PhpEws\\Type\\ExchangeImpersonationType',
+ 'GroupedItemsType' => '\\jamesiarmes\\PhpEws\\Type\\GroupedItemsType',
+ 'DailyRecurrencePatternType' => '\\jamesiarmes\\PhpEws\\Type\\DailyRecurrencePatternType',
+ 'FractionalPageViewType' => '\\jamesiarmes\\PhpEws\\Type\\FractionalPageViewType',
+ 'RuleOperationErrorType' => '\\jamesiarmes\\PhpEws\\Type\\RuleOperationErrorType',
+ 'PostReplyItemType' => '\\jamesiarmes\\PhpEws\\Type\\PostReplyItemType',
+ 'DelegatePermissionsType' => '\\jamesiarmes\\PhpEws\\Type\\DelegatePermissionsType',
+ 'CalendarViewType' => '\\jamesiarmes\\PhpEws\\Type\\CalendarViewType',
+ 'IsLessThanOrEqualToType' => '\\jamesiarmes\\PhpEws\\Type\\IsLessThanOrEqualToType',
+ 'SmartResponseType' => '\\jamesiarmes\\PhpEws\\Type\\SmartResponseType',
+ 'NumberedRecurrenceRangeType' => '\\jamesiarmes\\PhpEws\\Type\\NumberedRecurrenceRangeType',
+ 'ItemChangeDescriptionType' => '\\jamesiarmes\\PhpEws\\Type\\ItemChangeDescriptionType',
+ 'BasePathToElementType' => '\\jamesiarmes\\PhpEws\\Type\\BasePathToElementType',
+ 'BaseSubscriptionRequestType' => '\\jamesiarmes\\PhpEws\\Type\\BaseSubscriptionRequestType',
+ 'CalendarEventDetails' => '\\jamesiarmes\\PhpEws\\Type\\CalendarEventDetails',
+ 'AppMetadata' => '\\jamesiarmes\\PhpEws\\Type\\AppMetadata',
+ 'PushSubscriptionRequestType' => '\\jamesiarmes\\PhpEws\\Type\\PushSubscriptionRequestType',
+ 'SyncFolderHierarchyChangesType' => '\\jamesiarmes\\PhpEws\\Type\\SyncFolderHierarchyChangesType',
+ 'ItemIdType' => '\\jamesiarmes\\PhpEws\\Type\\ItemIdType',
+ 'WorkingPeriod' => '\\jamesiarmes\\PhpEws\\Type\\WorkingPeriod',
+ 'ConversationType' => '\\jamesiarmes\\PhpEws\\Type\\ConversationType',
+ 'AppType' => '\\jamesiarmes\\PhpEws\\Type\\AppType',
+ 'RulePredicateDateRangeType' => '\\jamesiarmes\\PhpEws\\Type\\RulePredicateDateRangeType',
+ 'FailedSearchMailboxType' => '\\jamesiarmes\\PhpEws\\Type\\FailedSearchMailboxType',
+ 'SyncFolderItemsCreateOrUpdateType' => '\\jamesiarmes\\PhpEws\\Type\\SyncFolderItemsCreateOrUpdateType',
+ 'PhysicalAddressDictionaryEntryType' => '\\jamesiarmes\\PhpEws\\Type\\PhysicalAddressDictionaryEntryType',
+ 'SuppressReadReceiptType' => '\\jamesiarmes\\PhpEws\\Type\\SuppressReadReceiptType',
+ 'FindItemParentType' => '\\jamesiarmes\\PhpEws\\Type\\FindItemParentType',
+ 'ProtectionRuleActionType' => '\\jamesiarmes\\PhpEws\\Type\\ProtectionRuleActionType',
+ 'IsEqualToType' => '\\jamesiarmes\\PhpEws\\Type\\IsEqualToType',
+ 'SuggestionsResponseType' => '\\jamesiarmes\\PhpEws\\Type\\SuggestionsResponseType',
+ 'DelegateUserType' => '\\jamesiarmes\\PhpEws\\Type\\DelegateUserType',
+ 'DiscoverySearchConfigurationType' => '\\jamesiarmes\\PhpEws\\Type\\DiscoverySearchConfigurationType',
+ 'RecurringMasterItemIdType' => '\\jamesiarmes\\PhpEws\\Type\\RecurringMasterItemIdType',
+ 'SerializedSecurityContextType' => '\\jamesiarmes\\PhpEws\\Type\\SerializedSecurityContextType',
+ 'OccurrenceItemIdType' => '\\jamesiarmes\\PhpEws\\Type\\OccurrenceItemIdType',
+ 'RequestAttachmentIdType' => '\\jamesiarmes\\PhpEws\\Type\\RequestAttachmentIdType',
+ 'DirectoryEntryType' => '\\jamesiarmes\\PhpEws\\Type\\DirectoryEntryType',
+ 'AddressListIdType' => '\\jamesiarmes\\PhpEws\\Type\\AddressListIdType',
+ 'DeleteFolderFieldType' => '\\jamesiarmes\\PhpEws\\Type\\DeleteFolderFieldType',
+ 'AndType' => '\\jamesiarmes\\PhpEws\\Type\\AndType',
+ 'SetRuleOperationType' => '\\jamesiarmes\\PhpEws\\Type\\SetRuleOperationType',
+ 'FreeBusyResponseType' => '\\jamesiarmes\\PhpEws\\Type\\FreeBusyResponseType',
+ 'MailTips' => '\\jamesiarmes\\PhpEws\\Type\\MailTips',
+ 'EndDateRecurrenceRangeType' => '\\jamesiarmes\\PhpEws\\Type\\EndDateRecurrenceRangeType',
+ 'NotType' => '\\jamesiarmes\\PhpEws\\Type\\NotType',
+ 'AlternateIdBaseType' => '\\jamesiarmes\\PhpEws\\Type\\AlternateIdBaseType',
+ 'MonthlyRegeneratingPatternType' => '\\jamesiarmes\\PhpEws\\Type\\MonthlyRegeneratingPatternType',
+ 'AggregateOnType' => '\\jamesiarmes\\PhpEws\\Type\\AggregateOnType',
+ 'MailboxStatisticsSearchResultType' => '\\jamesiarmes\\PhpEws\\Type\\MailboxStatisticsSearchResultType',
+ 'IsGreaterThanType' => '\\jamesiarmes\\PhpEws\\Type\\IsGreaterThanType',
+ 'YearlyRegeneratingPatternType' => '\\jamesiarmes\\PhpEws\\Type\\YearlyRegeneratingPatternType',
+ 'CancelCalendarItemType' => '\\jamesiarmes\\PhpEws\\Type\\CancelCalendarItemType',
+ 'RequestServerVersion' => '\\jamesiarmes\\PhpEws\\Type\\RequestServerVersion',
+ );
+ }
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php
new file mode 100644
index 00000000..c25d7ecc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Client.php
@@ -0,0 +1,1702 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Client.
+ */
+
+namespace jamesiarmes\PhpEws;
+
+use \jamesiarmes\PhpNtlm\SoapClient;
+
+/**
+ * Base class of the Exchange Web Services application.
+ *
+ * @package php-ews\Client
+ */
+class Client
+{
+ /**
+ * Microsoft Exchange 2007
+ *
+ * @var string
+ */
+ const VERSION_2007 = 'Exchange2007';
+
+ /**
+ * Microsoft Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const VERSION_2007_SP1 = 'Exchange2007_SP1';
+
+ /**
+ * Microsoft Exchange 2007 SP2
+ *
+ * @var string
+ */
+ const VERSION_2009 = 'Exchange2009';
+
+ /**
+ * Microsoft Exchange 2010
+ *
+ * @var string
+ */
+ const VERSION_2010 = 'Exchange2010';
+
+ /**
+ * Microsoft Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const VERSION_2010_SP1 = 'Exchange2010_SP1';
+
+ /**
+ * Microsoft Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const VERSION_2010_SP2 = 'Exchange2010_SP2';
+
+ /**
+ * Microsoft Exchange 2013.
+ *
+ * @var string
+ */
+ const VERSION_2013 = 'Exchange2013';
+
+ /**
+ * Microsoft Exchange 2013 SP1.
+ *
+ * @var string
+ */
+ const VERSION_2013_SP1 = 'Exchange2013_SP1';
+
+ /**
+ * Microsoft Exchange 2016.
+ *
+ * @var string
+ */
+ const VERSION_2016 = 'Exchange2016';
+
+ /**
+ * cURL options to be passed to the SOAP client.
+ *
+ * @var array
+ */
+ protected $curl_options = array();
+
+ /**
+ * SOAP headers used for requests.
+ *
+ * @var \SoapHeader[]
+ */
+ protected $headers = array();
+
+ /**
+ * Password to use when connecting to the Exchange server.
+ *
+ * @var string
+ */
+ protected $password;
+
+ /**
+ * Location of the Exchange server.
+ *
+ * @var string
+ */
+ protected $server;
+
+ /**
+ * SOAP client used to make the request
+ *
+ * @var \jamesiarmes\PhpNtlm\SoapClient
+ */
+ protected $soap;
+
+ /**
+ * Timezone to be used for all requests.
+ *
+ * @var string
+ */
+ protected $timezone;
+
+ /**
+ * Username to use when connecting to the Exchange server.
+ *
+ * @var string
+ */
+ protected $username;
+
+ /**
+ * Exchange impersonation
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExchangeImpersonationType
+ */
+ protected $impersonation;
+
+ /**
+ * Microsoft Exchange version that we are going to connect to
+ *
+ * @var string
+ *
+ * @see Client::VERSION_2007
+ * @see Client::VERSION_2007_SP1
+ * @see Client::VERSION_2007_SP2
+ * @see Client::VERSION_2007_SP3
+ * @see Client::VERSION_2010
+ * @see Client::VERSION_2010_SP1
+ * @see Client::VERSION_2010_SP2
+ */
+ protected $version;
+
+ /**
+ * Constructor for the ExchangeWebServices class
+ *
+ * @param string $server
+ * @param string $username
+ * @param string $password
+ * @param string $version
+ * One of the Client::VERSION_* constants.
+ */
+ public function __construct(
+ $server = null,
+ $username = null,
+ $password = null,
+ $version = self::VERSION_2013
+ ) {
+ // Set the object properties.
+ $this->setServer($server);
+ $this->setUsername($username);
+ $this->setPassword($password);
+ $this->setVersion($version);
+ }
+
+ /**
+ * Returns the SOAP Client that may be used to make calls against the server
+ *
+ * @return \jamesiarmes\PhpNtlm\SoapClient
+ */
+ public function getClient()
+ {
+ // If the SOAP client has yet to be initialized then do so now.
+ if (empty($this->soap)) {
+ $this->initializeSoapClient();
+ }
+
+ return $this->soap;
+ }
+
+ /**
+ * Sets the cURL options that will be set on the SOAP client.
+ *
+ * @param array $options
+ */
+ public function setCurlOptions(array $options)
+ {
+ $this->curl_options = $options;
+
+ // We need to reinitialize the SOAP client.
+ $this->soap = null;
+ }
+
+ /**
+ * Sets the impersonation property
+ *
+ * @param \jamesiarmes\PhpEws\Type\ExchangeImpersonationType $impersonation
+ */
+ public function setImpersonation($impersonation)
+ {
+ $this->impersonation = $impersonation;
+
+ // We need to re-build the SOAP headers.
+ $this->headers = array();
+ }
+
+ /**
+ * Sets the password property
+ *
+ * @param string $password
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+
+ // We need to reinitialize the SOAP client.
+ $this->soap = null;
+ }
+
+ /**
+ * Sets the server property
+ *
+ * @param string $server
+ */
+ public function setServer($server)
+ {
+ $this->server = $server;
+
+ // We need to reinitialize the SOAP client.
+ $this->soap = null;
+ }
+
+ /**
+ * Sets the timezone to be used for all requests.
+ *
+ * @param string $timezone
+ */
+ public function setTimezone($timezone)
+ {
+ $this->timezone = $timezone;
+
+ // We need to re-build the SOAP headers.
+ $this->headers = array();
+ }
+
+ /**
+ * Sets the user name property
+ *
+ * @param string $username
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+
+ // We need to reinitialize the SOAP client.
+ $this->soap = null;
+ }
+
+ /**
+ * Sets the version property
+ *
+ * @param string $version
+ */
+ public function setVersion($version)
+ {
+ $this->version = $version;
+
+ // We need to re-build the SOAP headers.
+ $this->headers = array();
+ }
+
+ /**
+ * Adds one or more delegates to a principal's mailbox and sets specific
+ * access permissions.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\AddDelegateType $request
+ * @return \jamesiarmes\PhpEws\Response\AddDelegateResponseMessageType
+ */
+ public function AddDelegate($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Adds a distribution group to the instant messaging (IM) list in the
+ * Unified Contact Store.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\AddDistributionGroupToImListType $request
+ * @return \jamesiarmes\PhpEws\Response\AddDistributionGroupToImListResponseMessageType
+ */
+ public function AddDistributionGroupToImList($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Adds an existing instant messaging (IM) contact to a group.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\AddImContactToGroup $request
+ * @return \jamesiarmes\PhpEws\Response\AddImContactToGroupResponseMessageType
+ */
+ public function AddImContactToGroup($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Adds a new instant messaging (IM) group to a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\AddImGroupType $request
+ * @return \jamesiarmes\PhpEws\Response\AddImGroupResponseMessageType
+ */
+ public function AddImGroup($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Adds a new contact to an instant messaging (IM) group.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\AddNewImContactToGroup $request
+ * @return \jamesiarmes\PhpEws\Response\AddNewImContactToGroupResponseMessageType
+ */
+ public function AddNewImContactToGroup($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Adds a new contact to a group based on a contact's phone number.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\AddNewTelUriContactToGroupType $request
+ * @return \jamesiarmes\PhpEws\Response\AddNewTelUriContactToGroupResponse
+ */
+ public function AddNewTelUriContactToGroup($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Sets a one-time or follow up action on all the items in a conversation.
+ *
+ * This operation allows you to categorize, move, copy, delete, and set the
+ * read state on all items in a conversation. Actions can also be set for
+ * new messages in a conversation.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\ApplyConversationActionType $request
+ * @return \jamesiarmes\PhpEws\Response\ApplyConversationActionResponseType
+ */
+ public function ApplyConversationAction($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Moves an item into the mailbox user's archive mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\ArchiveItemType $request
+ * @return \jamesiarmes\PhpEws\Response\ArchiveItemResponse
+ */
+ public function ArchiveItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Converts item and folder identifiers between formats that are accepted by
+ * Exchange Online, Exchange Online as part of Office 365, and on-premises
+ * versions of Exchange.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\ConvertIdType $request
+ * @return \jamesiarmes\PhpEws\Response\ConvertIdResponseType
+ */
+ public function ConvertId($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Copies folders in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\CopyFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\CopyFolderResponseType
+ */
+ public function CopyFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Copies items and puts the items in a different folder.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\CopyItemType $request
+ * @return \jamesiarmes\PhpEws\Response\CopyItemResponseType
+ */
+ public function CopyItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Creates either an item or file attachment and attaches it to the
+ * specified item.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\CreateAttachmentType $request
+ * @return \jamesiarmes\PhpEws\Response\CreateAttachmentResponseType
+ */
+ public function CreateAttachment($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Creates folders, calendar folders, contacts folders, tasks folders, and
+ * search folders.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\CreateFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\CreateFolderResponseType
+ */
+ public function CreateFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Creates a folder hierarchy.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\CreateFolderPathType $request
+ * @return \jamesiarmes\PhpEws\Response\CreateFolderPathResponseType
+ */
+ public function CreateFolderPath($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Creates items in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\CreateItemType $request
+ * @return \jamesiarmes\PhpEws\Response\CreateItemResponseType
+ */
+ public function CreateItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Creates a managed folder in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\CreateManagedFolderRequestType $request
+ * @return \jamesiarmes\PhpEws\Response\CreateManagedFolderResponseType
+ */
+ public function CreateManagedFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Creates a user configuration object on a folder.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\CreateUserConfigurationType $request
+ * @return \jamesiarmes\PhpEws\Response\CreateUserConfigurationResponseType
+ */
+ public function CreateUserConfiguration($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Deletes file and item attachments from an existing item in the Exchange
+ * store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\DeleteAttachmentType $request
+ * @return \jamesiarmes\PhpEws\Response\DeleteAttachmentResponseType
+ */
+ public function DeleteAttachment($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Deletes folders from a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\DeleteFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\DeleteFolderResponseType
+ */
+ public function DeleteFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Deletes items in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\DeleteItemType $request
+ * @return \jamesiarmes\PhpEws\Response\DeleteItemResponseType
+ */
+ public function DeleteItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Deletes a user configuration object on a folder.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\DeleteUserConfigurationType $request
+ * @return \jamesiarmes\PhpEws\Response\DeleteUserConfigurationResponseType
+ */
+ public function DeleteUserConfiguration($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Disables a mail app for Outlook.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\DisableAppType $request
+ * @return \jamesiarmes\PhpEws\Response\DisableAppResponseType
+ */
+ public function DisableApp($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Terminates a telephone call.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\DisconnectPhoneCallType $request
+ * @return \jamesiarmes\PhpEws\Response\DisconnectPhoneCallResponseMessageType
+ */
+ public function DisconnectPhoneCall($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Empties folders in a mailbox.
+ *
+ * Optionally, this operation enables you to delete the subfolders of the
+ * specified folder. When a subfolder is deleted, the subfolder and the
+ * messages within the subfolder are deleted.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\EmptyFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\EmptyFolderResponseType
+ */
+ public function EmptyFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Exposes the full membership of distribution lists.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\ExpandDLType $request
+ * @return \jamesiarmes\PhpEws\Response\ExpandDLResponseType
+ */
+ public function ExpandDL($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Exports items out of a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\ExportItemsType $request
+ * @return \jamesiarmes\PhpEws\Response\ExportItemsResponseType
+ */
+ public function ExportItems($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Enumerates a list of conversations in a folder.
+ *
+ * @param \jamesiarmes\PhpEws\Request\FindConversationType $request
+ * @return \jamesiarmes\PhpEws\Response\FindConversationResponseMessageType
+ */
+ public function FindConversation($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Finds subfolders of an identified folder and returns a set of properties
+ * that describe the set of subfolders.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\FindFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\FindFolderResponseType
+ */
+ public function FindFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Searches for items that are located in a user’s mailbox.
+ *
+ * This operation provides many ways to filter and format how search results
+ * are returned to the caller.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\FindItemType $request
+ * @return \jamesiarmes\PhpEws\Response\FindItemResponseType
+ */
+ public function FindItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Finds messages that meet the specified criteria.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\FindMessageTrackingReportRequestType $request
+ * @return \jamesiarmes\PhpEws\Response\FindMessageTrackingReportResponseMessageType
+ */
+ public function FindMessageTrackingReport($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Returns all persona objects from a specified Contacts folder or retrieves
+ * contacts that match a specified query string.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\FindPeopleType $request
+ * @return \jamesiarmes\PhpEws\Response\FindPeopleResponseMessageType
+ */
+ public function FindPeople($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves app manifests.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetAppManifestsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetAppManifestsResponseType
+ */
+ public function GetAppManifests($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the URL for the app marketplace that a client can visit to
+ * acquire apps to install in a mailbox.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetAppMarketplaceUrl $request
+ * @return \jamesiarmes\PhpEws\Response\GetAppMarketplaceUrlResponseMessageType
+ */
+ public function GetAppMarketplaceUrl($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves existing attachments on items in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetAttachmentType $request
+ * @return \jamesiarmes\PhpEws\Response\GetAttachmentResponseType
+ */
+ public function GetAttachment($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Gets a client access token for a mail app for Outlook.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetClientAccessTokenType $request
+ * @return \jamesiarmes\PhpEws\Response\GetClientAccessTokenResponseType
+ */
+ public function GetClientAccessToken($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves one or more sets of items that are organized in to nodes in a
+ * conversation.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetConversationItemsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetConversationItemsResponseType
+ */
+ public function GetConversationItems($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the delegate settings for a specified mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetDelegateType $request
+ * @return \jamesiarmes\PhpEws\Response\GetDelegateResponseMessageType
+ */
+ public function GetDelegate($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Returns configuration information for in-place holds, saved discovery
+ * searches, and the mailboxes that are enabled for discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetDiscoverySearchConfigurationType $request
+ * @return \jamesiarmes\PhpEws\Response\GetDiscoverySearchConfigurationResponseMessageType
+ */
+ public function GetDiscoverySearchConfiguration($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Used by pull subscription clients to request notifications from the
+ * Client Access server.
+ *
+ * The response returns an array of items and events that have occurred in a
+ * mailbox since the last the notification.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetEventsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetEventsResponseType
+ */
+ public function GetEvents($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Gets folders from the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\GetFolderResponseType
+ */
+ public function GetFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the mailboxes that are under a specific hold and the associated
+ * hold query.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetHoldOnMailboxesType $request
+ * @return \jamesiarmes\PhpEws\Response\GetHoldOnMailboxesResponseMessageType
+ */
+ public function GetHoldOnMailboxes($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the list of instant messaging (IM) groups and IM contact
+ * personas in a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetImItemListType $request
+ * @return \jamesiarmes\PhpEws\Response\GetImItemListResponseMessageType
+ */
+ public function GetImItemList($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves information about instant messaging (IM) groups and IM contact
+ * personas.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetImItemsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetImItemsResponse
+ */
+ public function GetImItems($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves Inbox rules in the identified user's mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetInboxRulesRequestType $request
+ * @return \jamesiarmes\PhpEws\Response\GetInboxRulesResponseType
+ */
+ public function GetInboxRules($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Gets folders from the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetItemType $request
+ * @return \jamesiarmes\PhpEws\Response\GetItemResponseType
+ */
+ public function GetItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the mail tips information for the specified mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetMailTipsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetMailTipsResponseMessageType
+ */
+ public function GetMailTips($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves tracking information about the specified messages.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetMessageTrackingReportRequestType $request
+ * @return \jamesiarmes\PhpEws\Response\GetMessageTrackingReportResponseMessageType
+ */
+ public function GetMessageTrackingReport($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves details about items that cannot be indexed.
+ *
+ * This includes, but is not limited to, the item identifier, an error code,
+ * an error description, when an attempt was made to index the item, and
+ * additional information about the file.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetNonIndexableItemDetailsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetNonIndexableItemDetailsResponseMessageType
+ */
+ public function GetNonIndexableItemDetails($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the count of items that cannot be indexed in a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetNonIndexableItemStatisticsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetNonIndexableItemStatisticsResponseMessageType
+ */
+ public function GetNonIndexableItemStatistics($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Provides the email account password expiration date for the current user.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetPasswordExpirationDateType $request
+ * @return \jamesiarmes\PhpEws\Response\GetPasswordExpirationDateResponseMessageType
+ */
+ public function GetPasswordExpirationDate($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves a set of properties that are associated with a persona.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetPersonaType $request
+ * @return \jamesiarmes\PhpEws\Response\GetPersonaResponseMessageType
+ */
+ public function GetPersona($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves information about the specified telephone call.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetPhoneCallInformationType $request
+ * @return \jamesiarmes\PhpEws\Response\GetPhoneCallInformationResponseMessageType
+ */
+ public function GetPhoneCallInformation($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves reminders for calendar and task items.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetRemindersType $request
+ * @return \jamesiarmes\PhpEws\Response\GetRemindersResponseMessageType
+ */
+ public function GetReminders($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the room lists that are available within the Exchange
+ * organization.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetRoomListsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetRoomListsResponseMessageType
+ */
+ public function GetRoomLists($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the rooms within the specified room list.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetRoomsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetRoomsResponseMessageType
+ */
+ public function GetRooms($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves a scoped set of searchable mailboxes for discovery searches.
+ *
+ * The scope of searchable mailboxes returned in the response is determined
+ * by the search filter and whether distribution group membership is
+ * expanded.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetSearchableMailboxesType $request
+ * @return \jamesiarmes\PhpEws\Response\GetSearchableMailboxesResponseMessageType
+ */
+ public function GetSearchableMailboxes($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieve the timezones supported by the server.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetServerTimeZonesType $request
+ * @return \jamesiarmes\PhpEws\Response\GetServerTimeZonesResponseType
+ */
+ public function GetServerTimeZones($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves configuration information for the specified type of service.
+ *
+ * This operation can return configuration settings for the Unified
+ * Messaging, Protection Rules, and Mail Tips services.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetServiceConfigurationType $request
+ * @return \jamesiarmes\PhpEws\Response\GetServiceConfigurationResponseMessageType
+ */
+ public function GetServiceConfiguration($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves the local folder identifier of a specified shared folder.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetSharingFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\GetSharingFolderResponseMessageType
+ */
+ public function GetSharingFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Gets an opaque authentication token that identifies a sharing invitation.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetSharingMetadataType $request
+ * @return \jamesiarmes\PhpEws\Response\GetSharingMetadataResponseMessageType
+ */
+ public function GetSharingMetadata($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Requests notifications from the Client Access server.
+ *
+ * The GetStreamingEvents response returns an array of items and events that
+ * have occurred in a mailbox since the last the notification.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetStreamingEventsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetStreamingEventsResponseType
+ */
+ public function GetStreamingEvents($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Provides detailed information about the availability of a set of users,
+ * rooms, and resources within a specified time period.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetUserAvailabilityRequestType $request
+ * @return \jamesiarmes\PhpEws\Response\GetUserAvailabilityResponseType
+ */
+ public function GetUserAvailability($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves a user configuration object from a folder.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetUserConfigurationType $request
+ * @return \jamesiarmes\PhpEws\Response\GetUserConfigurationResponseType
+ */
+ public function GetUserConfiguration($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Gets a mailbox user's Out of Office (OOF) settings and messages.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetUserOofSettingsRequest $request
+ * @return \jamesiarmes\PhpEws\Response\GetUserOofSettingsResponse
+ */
+ public function GetUserOofSettings($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves a user photo from Active Directory Domain Services (AD DS).
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetUserPhotoType $request
+ * @return \jamesiarmes\PhpEws\Response\GetUserPhotoResponseMessageType
+ */
+ public function GetUserPhoto($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Retrieves a list of all default, system folder, and personal tags that
+ * are associated with a user by means of a system policy or that were
+ * applied by the user.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\GetUserRetentionPolicyTagsType $request
+ * @return \jamesiarmes\PhpEws\Response\GetUserRetentionPolicyTagsResponseMessageType
+ */
+ public function GetUserRetentionPolicyTags($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Installs a mail app for Outlook in a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\InstallAppType $request
+ * @return \jamesiarmes\PhpEws\Response\InstallAppResponseType
+ */
+ public function InstallApp($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Sets the IsRead property on all items, in one or more folders, to
+ * indicate that all items are either read or unread.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\MarkAllItemsAsRead $request
+ * @return \jamesiarmes\PhpEws\Response\MarkAllItemsAsReadResponseType
+ */
+ public function MarkAllItemsAsRead($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Adds and removes users from the blocked email list and moves email
+ * messages to the Junk Email folder.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\MarkAsJunkType $request
+ * @return \jamesiarmes\PhpEws\Response\MarkAsJunkResponseType
+ */
+ public function MarkAsJunk($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Moves folders from a specified folder and puts them in another folder.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\MoveFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\MoveFolderResponseType
+ */
+ public function MoveFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Moves one or more items to a single destination folder.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\MoveItemType $request
+ * @return \jamesiarmes\PhpEws\Response\MoveItemResponseType
+ */
+ public function MoveItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Initiates a dismiss or snooze action on a reminder.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\PerformReminderActionType $request
+ * @return \jamesiarmes\PhpEws\Response\PerformReminderActionResponseMessageType
+ */
+ public function PerformReminderAction($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Initiates an outbound call and plays a message over the telephone.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\PlayOnPhoneType $request
+ * @return \jamesiarmes\PhpEws\Response\PlayOnPhoneResponseMessageType
+ */
+ public function PlayOnPhone($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Refreshes the specified local folder with the latest data from the folder
+ * that is being shared.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\RefreshSharingFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\RefreshSharingFolderResponseMessageType
+ */
+ public function RefreshSharingFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Removes contacts from the Lync instant messaging (IM) list when Lync uses
+ * Exchange for the contact store.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\RemoveContactFromImListType $request
+ * @return \jamesiarmes\PhpEws\Response\RemoveContactFromImListResponseMessageType
+ */
+ public function RemoveContactFromImList($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Removes one or more delegates from a user's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\RemoveDelegateType $request
+ * @return \jamesiarmes\PhpEws\Response\RemoveDelegateResponseMessageType
+ */
+ public function RemoveDelegate($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Removes a distribution group from the Lync instant messaging (IM) list
+ * when Lync uses Exchange for the contact store.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\RemoveDistributionGroupFromImListType $request
+ * @return \jamesiarmes\PhpEws\Response\RemoveDistributionGroupFromImListResponseMessageType
+ */
+ public function RemoveDistributionGroupFromImList($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Removes a single IM contact from an IM group.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\RemoveImContactFromGroupType $request
+ * @return \jamesiarmes\PhpEws\Response\RemoveImContactFromGroupResponseMessageType
+ */
+ public function RemoveImContactFromGroup($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Removes a single instant messaging (IM) group from a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\RemoveImGroupType $request
+ * @return \jamesiarmes\PhpEws\Response\RemoveImGroupResponseMessageType
+ */
+ public function RemoveImGroup($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Resolves ambiguous email addresses and display names.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\ResolveNamesType $request
+ * @return \jamesiarmes\PhpEws\Response\ResolveNamesResponseType
+ */
+ public function ResolveNames($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Searches mailboxes for occurrences of terms in mailbox items.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\SearchMailboxesType $request
+ * @return \jamesiarmes\PhpEws\Response\SearchMailboxesResponseType
+ */
+ public function SearchMailboxes($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Sends e-mail messages that are located in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\SendItemType $request
+ * @return \jamesiarmes\PhpEws\Response\SendItemResponseType
+ */
+ public function SendItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Sets a mailbox hold policy on mailboxes.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\SetHoldOnMailboxesType $request
+ * @return \jamesiarmes\PhpEws\Response\SetHoldOnMailboxesResponseMessageType
+ */
+ public function SetHoldOnMailboxes($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Changes the display name of an instant messaging (IM) group.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\SetImGroupType $request
+ * @return \jamesiarmes\PhpEws\Response\SetImGroupResponseMessageType
+ */
+ public function SetImGroup($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Sets a mailbox user's Out of Office (OOF) settings and message.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\SetUserOofSettingsRequest $request
+ * @return \jamesiarmes\PhpEws\Response\SetUserOofSettingsResponse
+ */
+ public function SetUserOofSettings($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Subscribes client applications to either push or pull notifications.
+ *
+ * It is important to be aware that the structure of the request messages
+ * and responses is different depending on the type of event notification.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\SubscribeType $request
+ * @return \jamesiarmes\PhpEws\Response\SubscribeResponseType
+ */
+ public function Subscribe($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Synchronizes folders between the computer that is running Microsoft
+ * Exchange Server and the client.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\SyncFolderHierarchyType $request
+ * @return \jamesiarmes\PhpEws\Response\SyncFolderHierarchyResponseType
+ */
+ public function SyncFolderHierarchy($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Synchronizes items between the Exchange server and the client.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\SyncFolderItemsType $request
+ * @return \jamesiarmes\PhpEws\Response\SyncFolderItemsResponseType
+ */
+ public function SyncFolderItems($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Uninstalls a mail app for Outlook.
+ *
+ * @since Exchange 2013
+ *
+ * @param \jamesiarmes\PhpEws\Request\UninstallAppType $request
+ * @return \jamesiarmes\PhpEws\Response\UninstallAppResponseType
+ */
+ public function UninstallApp($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Ends a pull notification subscription.
+ *
+ * Use this operation rather than letting a subscription timeout. This
+ * operation is only valid for pull notifications.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\UnsubscribeType $request
+ * @return \jamesiarmes\PhpEws\Response\UnsubscribeResponseType
+ */
+ public function Unsubscribe($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Updates delegate permissions on a principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\UpdateDelegateType $request
+ * @return \jamesiarmes\PhpEws\Response\UpdateDelegateResponseMessageType
+ */
+ public function UpdateDelegate($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Modifies properties of an existing item in the Exchange store.
+ *
+ * Each UpdateFolder operation consists of the following:
+ * - A FolderId element that specifies a folder to update.
+ * - An internal path of an element in the folder, as specified by the
+ * folder shape, which specifies the data to update.
+ * - A folder that contains the new value of the updated field, if the
+ * update is not a deletion.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\UpdateFolderType $request
+ * @return \jamesiarmes\PhpEws\Response\UpdateFolderResponseType
+ */
+ public function UpdateFolder($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Updates the authenticated user's Inbox rules by applying the specified
+ * operations.
+ *
+ * This operation is used to create an Inbox rule, to set an Inbox rule, or
+ * to delete an Inbox rule.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\UpdateInboxRulesRequestType $request
+ * @return \jamesiarmes\PhpEws\Response\UpdateInboxRulesResponseType
+ */
+ public function UpdateInboxRules($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Used to modify the properties of an existing item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @param \jamesiarmes\PhpEws\Request\UpdateItemType $request
+ * @return \jamesiarmes\PhpEws\Response\UpdateItemResponseType
+ */
+ public function UpdateItem($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Updates a user configuration object on a folder.
+ *
+ * @since Exchange 2010
+ *
+ * @param \jamesiarmes\PhpEws\Request\UpdateUserConfigurationType $request
+ * @return \jamesiarmes\PhpEws\Response\UpdateUserConfigurationResponseType
+ */
+ public function UpdateUserConfiguration($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Uploads a stream of items into an Exchange mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @param \jamesiarmes\PhpEws\Request\UploadItemsType $request
+ * @return \jamesiarmes\PhpEws\Response\UploadItemsResponseType
+ */
+ public function UploadItems($request)
+ {
+ return $this->makeRequest(__FUNCTION__, $request);
+ }
+
+ /**
+ * Initializes the SoapClient object to make a request
+ *
+ * @return \jamesiarmes\PhpNtlm\SoapClient
+ */
+ protected function initializeSoapClient()
+ {
+ $this->soap = new SoapClient(
+ dirname(__FILE__) . '/assets/services.wsdl',
+ array(
+ 'user' => $this->username,
+ 'password' => $this->password,
+ 'location' => 'https://' . $this->server . '/EWS/Exchange.asmx',
+ 'classmap' => ClassMap::getMap(),
+ 'curlopts' => $this->curl_options,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
+ )
+ );
+
+ return $this->soap;
+ }
+
+ /**
+ * Makes the SOAP call for a request.
+ *
+ * @param string $operation
+ * The operation to be called.
+ * @param \jamesiarmes\PhpEws\Request $request
+ * The request object for the operation.
+ * @return \jamesiarmes\PhpEws\Response
+ * The response object for the operation.
+ */
+ protected function makeRequest($operation, $request)
+ {
+ $this->getClient()->__setSoapHeaders($this->soapHeaders());
+ $response = $this->soap->{$operation}($request);
+
+ return $this->processResponse($response);
+ }
+
+ /**
+ * Process a response to verify that it succeeded and take the appropriate
+ * action
+ *
+ * @throws \Exception
+ *
+ * @param \stdClass $response
+ * @return \stdClass
+ */
+ protected function processResponse($response)
+ {
+ // If the soap call failed then we need to throw an exception.
+ $code = $this->soap->getResponseCode();
+ if ($code != 200) {
+ throw new \Exception(
+ "SOAP client returned status of $code.",
+ $code
+ );
+ }
+
+ return $response;
+ }
+
+ /**
+ * Builds the soap headers to be included with the request.
+ *
+ * @return \SoapHeader[]
+ */
+ protected function soapHeaders()
+ {
+ // If the headers have already been built, no need to do so again.
+ if (!empty($this->headers)) {
+ return $this->headers;
+ }
+
+ $this->headers = array();
+
+ // Set the schema version.
+ $this->headers[] = new \SoapHeader(
+ 'http://schemas.microsoft.com/exchange/services/2006/types',
+ 'RequestServerVersion Version="' . $this->version . '"'
+ );
+
+ // If impersonation was set then add it to the headers.
+ if (!empty($this->impersonation)) {
+ $this->headers[] = new \SoapHeader(
+ 'http://schemas.microsoft.com/exchange/services/2006/types',
+ 'ExchangeImpersonation',
+ $this->impersonation
+ );
+ }
+
+ if (!empty($this->timezone)) {
+ $this->headers[] = new \SoapHeader(
+ 'http://schemas.microsoft.com/exchange/services/2006/types',
+ 'TimeZoneContext',
+ array(
+ 'TimeZoneDefinition' => array(
+ 'Id' => $this->timezone,
+ )
+ )
+ );
+ }
+
+ return $this->headers;
+ }
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration.php
new file mode 100644
index 00000000..8b9ad583
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration.
+ */
+
+namespace jamesiarmes\PhpEws;
+
+/**
+ * Base class for Exchange Web Service Enumerations.
+ *
+ * @package php-ews\Enumeration
+ */
+class Enumeration extends Type
+{
+ /**
+ * Element value.
+ *
+ * @deprecated 1.0.0
+ * This property will be removed in a future release and should not be
+ * used. Instead, you should reference the constants implemented in the
+ * class directly.
+ *
+ * @var string
+ */
+ public $_;
+
+ /**
+ * Returns the value of this enumeration as a string..
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->_;
+ }
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AddInStateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AddInStateType.php
new file mode 100644
index 00000000..d95cdadd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AddInStateType.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\AddInStateType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Undocumented.
+ *
+ * @package php-ews\Enumeration
+ *
+ * @todo Update once documentation exists.
+ */
+class AddInStateType extends Enumeration
+{
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const FLAGGED = 'Flagged';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const OK = 'OK';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const REMOVED = 'Removed';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const UNDEFINED = 'Undefined';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const WITHDRAWING_SOON = 'WithdrawingSoon';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const WITHDRAWN = 'Withdrawn';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AffectedTaskOccurrencesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AffectedTaskOccurrencesType.php
new file mode 100644
index 00000000..402253d5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AffectedTaskOccurrencesType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\AffectedTaskOccurrencesType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines whether a task instance or a task master is deleted by a DeleteItem
+ * operation.
+ *
+ * @package php-ews\Enumeration
+ */
+class AffectedTaskOccurrencesType extends Enumeration
+{
+ /**
+ * A delete item request deletes the master task, and therefore all
+ * recurring tasks that are associated with the master task.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ALL = 'AllOccurrences';
+
+ /**
+ * A delete item request deletes only specific occurrences of a task.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SPECIFIED = 'SpecifiedOccurrenceOnly';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AggregateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AggregateType.php
new file mode 100644
index 00000000..ff4a73cd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AggregateType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\AggregateType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Indicates the maximum or minimum value of a property that is used for
+ * ordering groups of items.
+ *
+ * @package php-ews\Enumeration
+ */
+class AggregateType extends Enumeration
+{
+ /**
+ * Indicates that a maximum aggregation should be used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAXIMUM = 'Maximum';
+
+ /**
+ * Indicates that a minimum aggregation should be used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MINIMUM = 'Minimum';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AppointmentState.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AppointmentState.php
new file mode 100644
index 00000000..0321142f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AppointmentState.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\AppointmentState.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the status of the appointment.
+ *
+ * @package php-ews\Enumeration
+ */
+class AppointmentState extends Enumeration
+{
+ /**
+ * This appointment has been canceled.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANCELED = 4;
+
+ /**
+ * This appointment was forwarded.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FORWARD = 8;
+
+ /**
+ * This appointment is a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING = 1;
+
+ /**
+ * No flags have been set.
+ *
+ * This is only used for an appointment that does not include attendees.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NONE = 0;
+
+ /**
+ * This appointment has been received.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECEIVED = 2;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AvailabilityProxyRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AvailabilityProxyRequestType.php
new file mode 100644
index 00000000..bc3754d3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/AvailabilityProxyRequestType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\AvailabilityProxyRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines whether a proxy request is a cross-site or a cross-forest request.
+ *
+ * @package php-ews\Enumeration
+ */
+class AvailabilityProxyRequestType extends Enumeration
+{
+ /**
+ * Indicates that this request is cross-forest.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CROSS_FOREST = 'CrossForest';
+
+ /**
+ * Indicates that this request is cross-site.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CROSS_SITE = 'CrossSite';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeResponseType.php
new file mode 100644
index 00000000..50548348
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeResponseType.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\BodyTypeResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines how the body text is formatted in the response.
+ *
+ * @package php-ews\Enumeration
+ */
+class BodyTypeResponseType extends Enumeration
+{
+ /**
+ * The response will return the richest available content of body text.
+ *
+ * This is useful if it is unknown whether the content is text or HTML. The
+ * returned body will be text if the stored body is plain text. Otherwise,
+ * the response will return HTML if the stored body is in either HTML or RTF
+ * format.
+ *
+ * This is the default value.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BEST = 'Best';
+
+ /**
+ * The response will return an item body as HTML.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HTML = 'HTML';
+
+ /**
+ * The response will return an item body as plain text.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TEXT = 'Text';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeType.php
new file mode 100644
index 00000000..0aa92b38
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/BodyTypeType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\BodyTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the type of an item body.
+ *
+ * @package php-ews\Enumeration
+ */
+class BodyTypeType extends Enumeration
+{
+ /**
+ * Indicates that the body is in HTML.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HTML = 'HTML';
+
+ /**
+ * Indicates that the body is in text.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TEXT = 'Text';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemCreateOrDeleteOperationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemCreateOrDeleteOperationType.php
new file mode 100644
index 00000000..cc0c3099
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemCreateOrDeleteOperationType.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\CalendarItemCreateOrDeleteOperationType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes how meeting requests are handled after they are created.
+ *
+ * @package php-ews\Enumeration
+ */
+class CalendarItemCreateOrDeleteOperationType extends Enumeration
+{
+ /**
+ * The meeting request is sent to all attendees but is not saved in the Sent
+ * Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_ONLY_TO_ALL = 'SendOnlyToAll';
+
+ /**
+ * The meeting request is sent to all attendees and a copy is saved in the
+ * folder that is identified by the SavedItemFolderId element.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_TO_ALL_AND_SAVE_COPY = 'SendToAllAndSaveCopy';
+
+ /**
+ * If the item is a meeting request, it is saved as a calendar item but not
+ * sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_TO_NONE = 'SendToNone';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemTypeType.php
new file mode 100644
index 00000000..99f4c7b2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemTypeType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\CalendarItemTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of a calendar item.
+ *
+ * @package php-ews\Enumeration
+ */
+class CalendarItemTypeType extends Enumeration
+{
+ /**
+ * The item is an exception to a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EXCEPTION = 'Exception';
+
+ /**
+ * The item is an occurrence of a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OCCURRENCE = 'Occurrence';
+
+ /**
+ * The item is master for a set of recurring calendar items.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRING_MASTER = 'RecurringMaster';
+
+ /**
+ * The item is not associated with a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SINGLE = 'Single';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemUpdateOperationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemUpdateOperationType.php
new file mode 100644
index 00000000..60689f51
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarItemUpdateOperationType.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\CalendarItemUpdateOperationType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines how meeting updates are communicated after a calendar item is
+ * updated.
+ *
+ * @package php-ews\Enumeration
+ */
+class CalendarItemUpdateOperationType extends Enumeration
+{
+ /**
+ * The calendar item is updated and the meeting update is sent to all
+ * attendees but is not saved in the Sent Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_ONLY_TO_ALL = 'SendOnlyToAll';
+
+ /**
+ * The calendar item is updated and the meeting update is sent only to
+ * attendees that are affected by the change in the meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_ONLY_TO_CHANGED = 'SendOnlyToChanged';
+
+ /**
+ * The calendar item is updated, the meeting update is sent to all
+ * attendees, and a copy is saved in the Sent Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_TO_ALL_AND_SAVE_COPY = 'SendToAllAndSaveCopy';
+
+ /**
+ * The calendar item is updated, the meeting update is sent to all attendees
+ * that are affected by the change in the meeting, and a copy is saved in
+ * the Sent Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_TO_CHANGED_AND_SAVE_COPY = 'SendToChangedAndSaveCopy';
+
+ /**
+ * The calendar item is updated but updates are not sent to attendees.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_TO_NONE = 'SendToNone';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionLevelType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionLevelType.php
new file mode 100644
index 00000000..8331e546
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionLevelType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\CalendarPermissionLevelType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the permission level that a user has on a Calendar folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class CalendarPermissionLevelType extends PermissionLevelType
+{
+ /**
+ * Indicates that the user can view only free/busy time within the calendar.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const FREE_BUSY_ONLY = 'FreeBusyTimeOnly';
+
+ /**
+ * Indicates that the user can view free/busy time within the calendar and
+ * the subject and location of appointments.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const FREE_BUSY_SUBJECT_AND_LOCATION = 'FreeBusyTimeAndSubjectAndLocation';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionReadAccessType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionReadAccessType.php
new file mode 100644
index 00000000..4d6317e6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CalendarPermissionReadAccessType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\CalendarPermissionReadAccessType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Indicates whether a user has permission to read items within a Calendar
+ * folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class CalendarPermissionReadAccessType extends PermissionReadAccessType
+{
+ /**
+ * Indicates that the user has permission to view only free/busy time in the\
+ * calendar.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const TIME_ONLY = 'TimeOnly';
+
+ /**
+ * Indicates that the user has permission to view free/busy time in the
+ * calendar and the subject and location of appointments.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const TIME_SUBJECT_AND_LOCATION = 'TimeAndSubjectAndLocation';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ClientAccessTokenTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ClientAccessTokenTypeType.php
new file mode 100644
index 00000000..a802580d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ClientAccessTokenTypeType.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ClientAccessTokenTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of a client access token.
+ *
+ * @package php-ews\Enumeration
+ */
+class ClientAccessTokenTypeType extends Enumeration
+{
+ /**
+ * A caller identity client access token.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALLER_IDENTITY = 'CallerIdentity';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const CONNECTORS = 'Connectors';
+
+ /**
+ * An extension callback client access token.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const EXTENSION_CALLBACK = 'ExtensionCallback';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const EXTENSION_REST_API_CALLBACK = 'ExtensionRestApiCallback';
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ const LOKI = 'Loki';
+
+ /**
+ * Indicates that the client access token is a scoped token.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SCOPED_TOKEN = 'ScopedToken';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConferenceType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConferenceType.php
new file mode 100644
index 00000000..42c129c7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConferenceType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ConferenceType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of conferencing that is performed with a calendar item.
+ *
+ * @package php-ews\Enumeration
+ */
+class ConferenceType extends Enumeration
+{
+ /**
+ * The meeting is offline.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ const CHAT = 2;
+
+ /**
+ * The meeting is an Internet meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ const NET_MEETING = 0;
+
+ /**
+ * The meeting is an Internet show (such as a webinar).
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ const NET_SHOW = 1;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConflictResolutionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConflictResolutionType.php
new file mode 100644
index 00000000..f792ab62
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConflictResolutionType.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ConflictResolutionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of conflict resolution to try during an update.
+ *
+ * @package php-ews\Enumeration
+ */
+class ConflictResolutionType extends Enumeration
+{
+ /**
+ * If there is a conflict, the update operation will overwrite information.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ALWAYS_OVERWRITE = 'AlwaysOverwrite';
+
+ /**
+ * The update operation automatically resolves any conflict.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const AUTO_RESOLVE = 'AutoResolve';
+
+ /**
+ * If there is a conflict, the update operation fails and an error is
+ * returned.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NEVER_OVERWRITE = 'NeverOverwrite';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionFailureCauseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionFailureCauseType.php
new file mode 100644
index 00000000..e2e8d537
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionFailureCauseType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\EnumerationConnectionFailureCauseType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the reason for a disconnection from a telephone call.
+ *
+ * @package php-ews\Enumeration
+ */
+class ConnectionFailureCauseType extends Enumeration
+{
+ /**
+ * The called party did not answer.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NO_ANSWER = 'NoAnswer';
+
+ /**
+ * Call state is not disconnected or the disconnect reason is not known.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * Catch-all for other disconnect reasons.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const OTHER = 'Other';
+
+ /**
+ * The called party number was not available.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNAVAILABLE = 'Unavailable';
+
+ /**
+ * The called party line was busy.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const USER_BUSY = 'UserBusy';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionStatusType.php
new file mode 100644
index 00000000..e1f536eb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConnectionStatusType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ConnectionStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Provides a text description of the status of a streaming subscription.
+ *
+ * @package php-ews\Enumeration
+ */
+class ConnectionStatusType extends Enumeration
+{
+ /**
+ * Specifies that the connection has been closed.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CLOSED = 'Closed';
+
+ /**
+ * Specifies that the connection is open.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const OK = 'OK';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContactSourceType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContactSourceType.php
new file mode 100644
index 00000000..45aa6b20
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContactSourceType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ContactSourceType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes whether the contact is located in the Exchange store or Active
+ * Directory Domain Services (AD DS).
+ *
+ * @package php-ews\Enumeration
+ */
+class ContactSourceType extends Enumeration
+{
+ /**
+ * Indicates that the contact is stored in Active Directory.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACTIVE_DIRECTORY = 'ActiveDirectory';
+
+ /**
+ * Indicates that the contact is stored in the Exchange Store.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EXCHANGE_STORE = 'Store';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentComparisonType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentComparisonType.php
new file mode 100644
index 00000000..45e485c0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentComparisonType.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ContainmentComparisonType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Determines whether a search ignores cases and spaces.
+ *
+ * @package php-ews\Enumeration
+ */
+class ContainmentComparisonType extends Enumeration
+{
+ /**
+ * The comparison must be exact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EXACT = 'Exact';
+
+ /**
+ * The comparison ignores casing.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IGNORE_CASE = 'IgnoreCase';
+
+ /**
+ * The comparison ignores non-spacing characters.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IGNORE_CASE_AND_NON_SPACING_CHARS = 'IgnoreCaseAndNonSpacingCharacters';
+
+ /**
+ * The comparison ignores casing and non-spacing characters.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IGNORE_NON_SPACING_CHARS = 'IgnoreNonSpacingCharacters';
+
+ /**
+ * To be removed.
+ *
+ * @since Exchange 2007
+ * @deprecated Exchange 2007
+ *
+ * @var string
+ */
+ const LOOSE = 'Loose';
+
+ /**
+ * To be removed.
+ *
+ * @since Exchange 2007
+ * @deprecated Exchange 2007
+ *
+ * @var string
+ */
+ const LOOSE_AND_IGNORE_CASE = 'LooseAndIgnoreCase';
+
+ /**
+ * To be removed.
+ *
+ * @since Exchange 2007
+ * @deprecated Exchange 2007
+ *
+ * @var string
+ */
+ const LOOSE_AND_IGNORE_CASE_AND_IGNORE_NON_SPACING_CARS = 'LooseAndIgnoreCaseAndIgnoreNonSpace';
+
+ /**
+ * To be removed.
+ *
+ * @since Exchange 2007
+ * @deprecated Exchange 2007
+ *
+ * @var string
+ */
+ const LOOSE_AND_IGNORE_NON_SPACING_CHARS = 'LooseAndIgnoreNonSpace';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentModeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentModeType.php
new file mode 100644
index 00000000..d67b612f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ContainmentModeType.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ContainmentModeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Identifies the boundaries of a search.
+ *
+ * @package php-ews\Enumeration
+ */
+class ContainmentModeType extends Enumeration
+{
+ /**
+ * The comparison is between an exact phrase in the string and the constant.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EXACT_PHRASE = 'ExactPhrase';
+
+ /**
+ * The comparison is between the full string and the constant.
+ *
+ * The property value and the supplied constant are precisely the same.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FULL_STRING = 'FullString';
+
+ /**
+ * The comparison is between a prefix on individual words in the string and
+ * the constant.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PREFIX_ON_WORDS = 'PrefixOnWords';
+
+ /**
+ * The comparison is between the string prefix and the constant.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PREFIXED = 'Prefixed';
+
+ /**
+ * The comparison is between a substring of the string and the constant.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SUBSTRING = 'Substring';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationActionTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationActionTypeType.php
new file mode 100644
index 00000000..9dc9eb90
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationActionTypeType.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ConversationActionTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Contains the action to perform on a conversation specified by a
+ * ConversationId.
+ *
+ * @package php-ews\Enumeration
+ */
+class ConversationActionTypeType extends Enumeration
+{
+ /**
+ * The current items and new items in the conversation will automatically be
+ * set with the categories identified by the Categories property.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const ALWAYS_CATEGORIZE = 'AlwaysCategorize';
+
+ /**
+ * The current items and new items in the conversation will automatically be
+ * deleted.
+ *
+ * The deletion mode is set by the DeleteType property.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const ALWAYS_DELETE = 'AlwaysDelete';
+
+ /**
+ * The current items and new items in the conversation will automatically be
+ * moved to the folder identified by the DestinationFolderId property.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const ALWAYS_MOVE = 'AlwaysMove';
+
+ /**
+ * The current items in the conversation will be copied to the folder
+ * identified by the DestinationFolderId property.
+ *
+ * Subsequent items in the conversation will not be copied.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const COPY = 'Copy';
+
+ /**
+ * The current items in the conversation will be deleted.
+ *
+ * Subsequent items in the conversation will not be deleted. The deletion
+ * mode is set by the DeleteType property.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const DELETE = 'Delete';
+
+ /**
+ * The current items in the conversation will be moved to the folder
+ * identified by the DestinationFolderId property.
+ *
+ * Subsequent items in the conversation will not be moved.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const MOVE = 'Move';
+
+ /**
+ * The current items in the conversation will have their read state set.
+ *
+ * The read state is set by the IsRead property.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const SET_READ_STATE = 'SetReadState';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationNodeSortOrder.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationNodeSortOrder.php
new file mode 100644
index 00000000..3b7320f8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationNodeSortOrder.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ConversationNodeSortOrder.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the sort order used for the result of a GetConversationItems request.
+ *
+ * @package php-ews\Enumeration
+ */
+class ConversationNodeSortOrder extends Enumeration
+{
+ /**
+ * Order the conversations by their date in ascending order.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DATE_ORDER_ASC = 'DateOrderAscending';
+
+ /**
+ * Order the conversations by their date in descending order.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DATE_ORDER_DESC = 'DateOrderDescending';
+
+ /**
+ * Returns the conversations according to the tree in ascending order.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TREE_ORDER_ASC = 'TreeOrderAscending';
+
+ /**
+ * Returns the conversations according to the tree in descending order.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TREE_ORDER_DESC = 'TreeOrderDescending';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationQueryTraversalType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationQueryTraversalType.php
new file mode 100644
index 00000000..634c2fcc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ConversationQueryTraversalType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ConversationQueryTraversalType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of traversal to use for a folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class ConversationQueryTraversalType extends Enumeration
+{
+ /**
+ * Consider both direct children as well as all children contained within
+ * those children as well as the children's children, etc.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DEEP = 'Deep';
+
+ /**
+ * Consider only direct children of the parent in question.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SHALLOW = 'Shallow';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CreateActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CreateActionType.php
new file mode 100644
index 00000000..29dd5d0c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/CreateActionType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\CreateActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the action for uploading an item into a mailbox.
+ *
+ * @package php-ews\Enumeration
+ */
+class CreateActionType extends Enumeration
+{
+ /**
+ * Indicates that a new copy of the original item is uploaded to the
+ * mailbox.
+ *
+ * The ItemId element must not be present if the CreateNew value is used.
+ * The new item identifier is returned in the response.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const CREATE = 'CreateNew';
+
+ /**
+ * Specifies that the item indicated by the ItemId element will be updated.
+ *
+ * An error is returned if the ItemId element is not present or if the item
+ * does not exist in the folder identified by the ParentFolderId element.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const UPDATE = 'Update';
+
+ /**
+ * Indicates that an attempt is first made to update the item.
+ *
+ * If the item does not exist in the folder specified by the ParentFolderId
+ * element, a new item is created.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const UPDATE_OR_CREATE = 'UpdateOrCreate';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DateTimePrecisionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DateTimePrecisionType.php
new file mode 100644
index 00000000..b5f6924a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DateTimePrecisionType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DateTimePrecisionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the precision for returned date/time values.
+ *
+ * @package php-ews\Enumeration
+ */
+class DateTimePrecisionType extends Enumeration
+{
+ /**
+ * Indicates that date/time values should be precise to the millisecond.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const MILLISECONDS = 'Milliseconds';
+
+ /**
+ * Indicates that date/time values should be precise to the second.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const SECONDS = 'Seconds';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekIndexType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekIndexType.php
new file mode 100644
index 00000000..911ccb2a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekIndexType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DayOfWeekIndexType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of a calendar item.
+ *
+ * @package php-ews\Enumeration
+ */
+class DayOfWeekIndexType extends Enumeration
+{
+ /**
+ * Represents the first day of a week.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FIRST = 'First';
+
+ /**
+ * Represents the fourth day of a week.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOURTH = 'Fourth';
+
+ /**
+ * Represents the last day of a week.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST = 'Last';
+
+ /**
+ * Represents the second day of a week.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SECOND = 'Second';
+
+ /**
+ * Represents the Third day of a week.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const THIRD = 'Third';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekType.php
new file mode 100644
index 00000000..a40c78f7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DayOfWeekType.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DayOfWeekType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents a day of the week.
+ *
+ * @package php-ews\Enumeration
+ */
+class DayOfWeekType extends Enumeration
+{
+ /**
+ * Represents a day of the week.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DAY = 'Day';
+
+ /**
+ * Represents Friday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FRIDAY = 'Friday';
+
+ /**
+ * Represents Monday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MONDAY = 'Monday';
+
+ /**
+ * Represents Saturday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SATURDAY = 'Saturday';
+
+ /**
+ * Represents Sunday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SUNDAY = 'Sunday';
+
+ /**
+ * Represents Thursday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const THURSDAY = 'Thursday';
+
+ /**
+ * Represents Tuesday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TUESDAY = 'Tuesday';
+
+ /**
+ * Represents Wednesday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WEDNESDAY = 'Wednesday';
+
+ /**
+ * Represents a weekday.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WEEKDAY = 'Weekday';
+
+ /**
+ * Represents a weekend day.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WEEKEND_DAY = 'WeekendDay';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DaysOfWeekType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DaysOfWeekType.php
new file mode 100644
index 00000000..bb81fe25
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DaysOfWeekType.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DaysOfWeekType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents days of the week that are used in item recurrence patterns.
+ *
+ * @package php-ews\Enumeration
+ *
+ * @todo Make this an array type that separates values by space in the
+ * __toString() method.
+ */
+class DaysOfWeekType extends DayOfWeekType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DefaultShapeNamesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DefaultShapeNamesType.php
new file mode 100644
index 00000000..b36fb6b0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DefaultShapeNamesType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the set of properties to return in an item or folder response.
+ *
+ * @package php-ews\Enumeration
+ */
+class DefaultShapeNamesType extends Enumeration
+{
+ /**
+ * Returns all the properties used by the Exchange Business Logic layer to
+ * construct a folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ALL_PROPERTIES = 'AllProperties';
+
+ /**
+ * Returns a set of properties that are defined as the default for the item
+ * or folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DEFAULT_PROPERTIES = 'Default';
+
+ /**
+ * Returns only the item or folder ID.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ID_ONLY = 'IdOnly';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DelegateFolderPermissionLevelType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DelegateFolderPermissionLevelType.php
new file mode 100644
index 00000000..b98d23ca
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DelegateFolderPermissionLevelType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DelegateFolderPermissionLevelType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Contains the permissions for a default folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class DelegateFolderPermissionLevelType extends Enumeration
+{
+ /**
+ * The delegate user can read and create items in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const AUTHOR = 'Author';
+
+ /**
+ * The delegate user has custom access permissions to the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const CUSTOM = 'Custom';
+
+ /**
+ * The delegate user can read, create, and modify items in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const EDITOR = 'Editor';
+
+ /**
+ * The delegate user has no access permissions to the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * The delegate user can read items in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const REVIEWER = 'Reviewer';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DeliverMeetingRequestsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DeliverMeetingRequestsType.php
new file mode 100644
index 00000000..cf7649bf
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DeliverMeetingRequestsType.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DeliverMeetingRequestsType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines how meeting requests are handled between the delegate and the
+ * principal.
+ *
+ * @package php-ews\Enumeration
+ */
+class DeliverMeetingRequestsType extends Enumeration
+{
+ /**
+ * Meeting requests are forwarded to the delegate and remain in the Inbox
+ * folder in the principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATES_AND_ME = 'DelegatesAndMe';
+
+ /**
+ * Meeting requests are forwarded to the delegate and remain in the Inbox
+ * folder in the principal's mailbox, but the Accept, Tentative, and Decline
+ * buttons do not appear in the Microsoft Office Outlook reading pane.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATES_AND_SEND_INFO_TO_ME = 'DelegatesAndSendInformationToMe';
+
+ /**
+ * Meeting requests are forwarded to the delegate and moved to the Deleted
+ * Items folder in the principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATES_ONLY = 'DelegatesOnly';
+
+ /**
+ * Meeting requests are not forwarded to the delegate.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NO_FORWARD = 'NoForward';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DictionaryURIType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DictionaryURIType.php
new file mode 100644
index 00000000..15dafbf9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DictionaryURIType.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DictionaryURIType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Identifies the dictionary that contains the member to return.
+ *
+ * @package php-ews\Enumeration
+ */
+class DictionaryURIType extends Enumeration
+{
+ /**
+ * Represents the e-mail address of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_EMAIL_ADDRESS = 'contacts:EmailAddress';
+
+ /**
+ * Represents the instant messaging address of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_IM_ADDRESS = 'contacts:ImAddress';
+
+ /**
+ * Represents the phone number of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHONE_NUMBER = 'contacts:PhoneNumber';
+
+ /**
+ * Represents the city of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHYSICAL_ADDRESS_CITY = 'contacts:PhysicalAddress:City';
+
+ /**
+ * Represents the country of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHYSICAL_ADDRESS_COUNTRY = 'contacts:PhysicalAddress:Country';
+
+ /**
+ * Represents the postal code of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHYSICAL_ADDRESS_POSTAL_CODE = 'contacts:PhysicalAddress:PostalCode';
+
+ /**
+ * Represents the state of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHYSICAL_ADDRESS_STATE = 'contacts:PhysicalAddress:State';
+
+ /**
+ * Represents the street address of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHYSICAL_ADDRESS_STREET = 'contacts:PhysicalAddress:Street';
+
+ /**
+ * Represents a member of a distribution list.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DISTRIBUTION_LIST_MEMBERS_MEMBER = 'distributionlist:Members:Member';
+
+ /**
+ * Represents the message header of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_INTERNET_MESSAGE_HEADER = 'item:InternetMessageHeader';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisableReasonType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisableReasonType.php
new file mode 100644
index 00000000..d399c877
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisableReasonType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DisableReasonType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the reason for disabling an app.
+ *
+ * @package php-ews\Enumeration
+ */
+class DisableReasonType extends Enumeration
+{
+ /**
+ * To improve mobile client performance.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MOBILE_CLIENT_PERFORMANCE = 'MobileClientPerformance';
+
+ /**
+ * No reason given.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NO_REASON = 'NoReason';
+
+ /**
+ * To improve email client performance.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const OUTLOOK_CLIENT_PERFORMANCE = 'OutlookClientPerformance';
+
+ /**
+ * To improve Web app client performance.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const OWA_CLIENT_PERFORMANCE = 'OWAClientPerformance';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisposalType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisposalType.php
new file mode 100644
index 00000000..87297890
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DisposalType.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DisposalType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Indicates how items are deleted.
+ *
+ * @package php-ews\Enumeration
+ */
+class DisposalType extends Enumeration
+{
+ /**
+ * Indicates that items are permanently removed from the database.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const HARD_DELETE = 'HardDelete';
+
+ /**
+ * Indicates that items are moved to the Deleted Items folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const MOVE_TO_DELETED_ITEMS = 'MoveToDeletedItems';
+
+ /**
+ * Indicates that items are moved to the dumpster if the dumpster is
+ * enabled.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const SOFT_DELETE = 'SoftDelete';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedFolderIdNameType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedFolderIdNameType.php
new file mode 100644
index 00000000..1c458e56
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedFolderIdNameType.php
@@ -0,0 +1,394 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents default calendar ids.
+ *
+ * @package php-ews\Enumeration
+ */
+class DistinguishedFolderIdNameType extends Enumeration
+{
+ /**
+ * Represents the admin audit logs folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ADMIN_AUDIT_LOGS = 'adminauditlogs';
+
+ /**
+ * Represents the archive deleted items folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ARCHIVE_DELETED = 'archivedeleteditems';
+
+ /**
+ * Represents the archive Inbox folder.
+ *
+ * @since Exchange 2013 CU5
+ *
+ * @var string
+ */
+ const ARCHIVE_INBOX = 'archiveinbox';
+
+ /**
+ * Represents the root archive message folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ARCHIVE_MESSAGE_ROOT = 'archivemsgfolderroot';
+
+ /**
+ * Represents the archive recoverable items deletions folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ARCHIVE_RECOVERABLE_DELETIONS = 'Archiverecoverableitemsdeletions';
+
+ /**
+ * Represents the archive recoverable items purges folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ARCHIVE_RECOVERABLE_PURGES = 'Archiverecoverableitemspurges';
+
+ /**
+ * Represents the archive recoverable items root folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ARCHIVE_RECOVERABLE_ROOT = 'archiverecoverableitemsroot';
+
+ /**
+ * Represents the archive recoverable items versions folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ARCHIVE_RECOVERABLE_VERSIONS = 'Archiverecoverableitemsversions';
+
+ /**
+ * Represents the root archive folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ARCHIVE_ROOT = 'archiveroot';
+
+ /**
+ * Represents the Calendar folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR = 'calendar';
+
+ /**
+ * Represents the conflicts folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONFLICTS = 'conflicts';
+
+ /**
+ * Represents the Contacts folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS = 'contacts';
+
+ /**
+ * Represents the conversation history folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_HISTORY = 'conversationhistory';
+
+ /**
+ * Represents the Deleted Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DELETED = 'deleteditems';
+
+ /**
+ * Represents the directory folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DIRECTORY = 'directory';
+
+ /**
+ * Represents the Drafts folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DRAFTS = 'drafts';
+
+ /**
+ * Represents the Favorites folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const FAVORITES = 'favorites';
+
+ /**
+ * Represents the IM contact list folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const IM_CONTACT_LIST = 'imcontactlist';
+
+ /**
+ * Represents the Inbox folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INBOX = 'inbox';
+
+ /**
+ * Represents the Journal folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const JOURNAL = 'journal';
+
+ /**
+ * Represents the Junk E-mail folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const JUNK = 'junkemail';
+
+ /**
+ * Represents the local failures folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const LOCAL_FAILURES = 'localfailures';
+
+ /**
+ * Represents the message folder root.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_ROOT = 'msgfolderroot';
+
+ /**
+ * Represents the My Contacts folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MY_CONTACTS = 'mycontacts';
+
+ /**
+ * Represents the Notes folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOTES = 'notes';
+
+ /**
+ * Represents the Outbox folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OUTBOX = 'outbox';
+
+ /**
+ * Represents the people connect folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PEOPLE_CONNECT = 'peopleconnect';
+
+ /**
+ * Indicates the URL of the public folders root folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PUBLIC_FOLDERS_ROOT = 'publicfoldersroot';
+
+ /**
+ * Represents the quick contacts folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const QUICK_CONTACTS = 'quickcontacts';
+
+ /**
+ * Represents the recipient cache folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const RECIPIENT_CACHE = 'recipientcache';
+
+ /**
+ * Represents the dumpster deletions folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECOVERABLE_DELETIONS = 'recoverableitemsdeletions';
+
+ /**
+ * Represents the dumpster purges folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECOVERABLE_PURGES = 'recoverableitemspurges';
+
+ /**
+ * Represents the dumpster root folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECOVERABLE_ROOT = 'recoverableitemsroot';
+
+ /**
+ * Represents the dumpster versions folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECOVERABLE_VERSIONS = 'recoverableitemsversions';
+
+ /**
+ * Represents the root of the mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ROOT = 'root';
+
+ /**
+ * Represents the Search Folders folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEARCH = 'searchfolders';
+
+ /**
+ * Represents the Sent Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SENT = 'sentitems';
+
+ /**
+ * Represents the server failures folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SERVER_FAILURES = 'serverfailures';
+
+ /**
+ * Represents the sync issues folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SYNC_ISSUES = 'syncissues';
+
+ /**
+ * Represents the Tasks folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASKS = 'tasks';
+
+ /**
+ * Represents the todo search folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TODO_SEARCH = 'todosearch';
+
+ /**
+ * Represents the Voice Mail folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const VOICE_MAIL = 'voicemail';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedPropertySetType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedPropertySetType.php
new file mode 100644
index 00000000..ea69cfe9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedPropertySetType.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DistinguishedPropertySetType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the well-known property set IDs for extended MAPI properties.
+ *
+ * @package php-ews\Enumeration
+ */
+class DistinguishedPropertySetType extends Enumeration
+{
+ /**
+ * Identifies the address property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ADDRESS = 'Address';
+
+ /**
+ * Identifies the appointment property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const APPOINTMENT = 'Appointment';
+
+ /**
+ * Identifies the calendar assistant property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_ASSISTANT = 'CalendarAssistant';
+
+ /**
+ * Identifies the common property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const COMMON = 'Common';
+
+ /**
+ * Identifies the Internet headers property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INTERNET_HEADERS = 'InternetHeaders';
+
+ /**
+ * Identifies the meeting property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING = 'Meeting';
+
+ /**
+ * Identifies the public strings property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PUBLIC_STRINGS = 'PublicStrings';
+
+ /**
+ * Identifies the sharing property set ID by name.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ const SHARING = 'Sharing';
+
+ /**
+ * Indicates a task.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const TASK = 'Task';
+
+ /**
+ * Identifies the unified messaging property set ID by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNIFIED_MESSAGING = 'UnifiedMessaging';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedUserType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedUserType.php
new file mode 100644
index 00000000..b4a0fbdb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/DistinguishedUserType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\DistinguishedUserType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Identifies Anonymous and Default user accounts for delegate access.
+ *
+ * @package php-ews\Enumeration
+ */
+class DistinguishedUserType extends Enumeration
+{
+ /**
+ * Describes the delegate access settings that anonymous users have on the
+ * principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ANONYMOUS = 'Anonymous';
+
+ /**
+ * Describes the default setting for delegate users who are added to the
+ * principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DEFAULT_USER = 'Default';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ElcFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ElcFolderType.php
new file mode 100644
index 00000000..ba657e22
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ElcFolderType.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ElcFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of folder used in a retention policy.
+ *
+ * @package php-ews\Enumeration
+ */
+class ElcFolderType extends Enumeration
+{
+ /**
+ * Indicates that the folder is an all folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ALL = 'All';
+
+ /**
+ * Indicates that the folder is a calendar folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR = 'Calendar';
+
+ /**
+ * Indicates that the folder is a contacts folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONTACTS = 'Contacts';
+
+ /**
+ * Indicates that the folder is a conversation history folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_HISTORY = 'ConversationHistory';
+
+ /**
+ * Indicates that the folder is a deleted items folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DELETED_ITEMS = 'DeletedItems';
+
+ /**
+ * Indicates that the folder is a drafts folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DRAFTS = 'Drafts';
+
+ /**
+ * Indicates that the folder is an inbox folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INBOX = 'Inbox';
+
+ /**
+ * Indicates that the folder is a journal folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const JOURNAL = 'Journal';
+
+ /**
+ * Indicates that the folder is a junk email folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const JUNK_EMAIL = 'JunkEmail';
+
+ /**
+ * Indicates that the folder is a managed custom folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MANAGED_CUSTOM_FOLDER = 'ManagedCustomFolder';
+
+ /**
+ * Indicates that the folder is a non implemented root folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NON_IMPLEMENTED_ROOT = 'NonIpmRoot';
+
+ /**
+ * Indicates that the folder is a notes folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NOTES = 'Notes';
+
+ /**
+ * Indicates that the folder is a outbox folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const OUTBOX = 'Outbox';
+
+ /**
+ * Indicates that the folder is a personal folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONAL = 'Personal';
+
+ /**
+ * Indicates that the folder is a recoverable items folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const RECOVERABLE_ITEMS = 'RecoverableItems';
+
+ /**
+ * Indicates that the folder is an RSS subscription folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const RSS_SUBSCRIPTION = 'RssSubscriptions';
+
+ /**
+ * Indicates that the folder is a sent items folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SENT_ITEMS = 'SentItems';
+
+ /**
+ * Indicates that the folder is a sync issues folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SYNC_ISSUES = 'SyncIssues';
+
+ /**
+ * Indicates that the folder is a tasks folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TASKS = 'Tasks';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/EmailAddressKeyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/EmailAddressKeyType.php
new file mode 100644
index 00000000..66b32fd9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/EmailAddressKeyType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\EmailAddressKeyType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the key for an email address.
+ *
+ * @package php-ews\Enumeration
+ */
+class EmailAddressKeyType extends Enumeration
+{
+ /**
+ * Key for a contacts first email address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EMAIL_ADDRESS_1 = 'EmailAddress1';
+
+ /**
+ * Key for a contacts second email address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EMAIL_ADDRESS_2 = 'EmailAddress2';
+
+ /**
+ * Key for a contacts third email address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EMAIL_ADDRESS_3 = 'EmailAddress3';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExceptionPropertyURIType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExceptionPropertyURIType.php
new file mode 100644
index 00000000..491e7198
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExceptionPropertyURIType.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ExceptionPropertyURIType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines a property of an occurrence of a recurring item.
+ *
+ * @package php-ews\Enumeration
+ */
+class ExceptionPropertyURIType extends Enumeration
+{
+ /**
+ * Identifies the content as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ATTACHMENT_CONTENT = 'attachment:Content';
+
+ /**
+ * Identifies the content type as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ATTACHMENT_CONTENT_TYPE = 'attachment:ContentType';
+
+ /**
+ * Identifies the attachment name as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ATTACHMENT_NAME = 'attachment:Name';
+
+ /**
+ * Identifies the DayOfMonth as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_DAY_OF_MONTH = 'recurrence:DayOfMonth';
+
+ /**
+ * Identifies the day of week index as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_DAY_OF_WEEK_INDEX = 'recurrence:DayOfWeekIndex';
+
+ /**
+ * Identifies the DaysOfWeek property as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_DAYS_OF_WEEK = 'recurrence:DaysOfWeek';
+
+ /**
+ * Identifies the interval as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_INTERVAL = 'recurrence:Interval';
+
+ /**
+ * Identifies the month field as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_MONTH = 'recurrence:Month';
+
+ /**
+ * Identifies the number of occurrences as containing an error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_NUMBER_OF_OCCURRENCES = 'recurrence:NumberOfOccurrences';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExchangeVersionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExchangeVersionType.php
new file mode 100644
index 00000000..28fa614c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExchangeVersionType.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ExchangeVersionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the versioning information that identifies the schema version to
+ * target for a request.
+ *
+ * @package php-ews\Enumeration
+ */
+class ExchangeVersionType extends Enumeration
+{
+ /**
+ * Target the schema files for the initial release version of Exchange 2007.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const EXCHANGE_2007 = 'Exchange2007';
+
+ /**
+ * Target the schema files for Exchange 2007 Service Pack 1 (SP1), Exchange
+ * 2007 Service Pack 2 (SP2), and Exchange 2007 Service Pack 3 (SP3).
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const EXCHANGE_2007_SP1 = 'Exchange2007_SP1';
+
+ /**
+ * Microsoft Exchange 2007 SP2
+ *
+ * @var string
+ */
+ const VERSION_2009 = 'Exchange2009';
+
+ /**
+ * Target the schema files for Exchange 2010.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCHANGE_2010 = 'Exchange2010';
+
+ /**
+ * Target the schema files for Exchange 2010 Service Pack 1 (SP1).
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const EXCHANGE_2010_SP1 = 'Exchange2010_SP1';
+
+ /**
+ * Target the schema files for Exchange 2010 Service Pack 2 (SP2) and
+ * Exchange 2010 Service Pack 3 (SP3).
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const EXCHANGE_2010_SP2 = 'Exchange2010_SP2';
+
+ /**
+ * Target the schema files for Exchange 2013.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const EXCHANGE_2013 = 'Exchange2013';
+
+ /**
+ * Target the schema files for Exchange 2013 Service Pack 1 (SP1).
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ const EXCHANGE_2013_SP1 = 'Exchange2013_SP1';
+
+ /**
+ * Target the schema files for Exchange 2016.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ const VERSION_2016 = 'Exchange2016';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExternalAudience.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExternalAudience.php
new file mode 100644
index 00000000..196235d0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ExternalAudience.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ExternalAudience.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Identifies to whom external Out of Office (OOF) messages are sent..
+ *
+ * @package php-ews\Enumeration
+ */
+class ExternalAudience extends Enumeration
+{
+ /**
+ * E-mail senders outside the mailbox user's organization who send messages
+ * to the user will receive an external OOF message response..
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ALL = 'All';
+
+ /**
+ * E-mail senders outside the mailbox user's organization who send messages
+ * to the user will only receive an external OOF message response if the
+ * sender is in the user's Exchange store contact list.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const KNOWN = 'Known';
+
+ /**
+ * E-mail senders outside the mailbox user's organization who send messages
+ * to the user will not receive an external OOF message response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NONE = 'None';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FileAsMappingType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FileAsMappingType.php
new file mode 100644
index 00000000..f062c305
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FileAsMappingType.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\FileAsMappingType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines how to construct what is displayed for a contact.
+ *
+ * @package php-ews\Enumeration
+ */
+class FileAsMappingType extends Enumeration
+{
+ /**
+ * File as mapping for "company".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const COMPANY = 'Company';
+
+ /**
+ * File as mapping for "last name, first name".
+ *
+ * @since Exchange 2007
+ *
+ * @var
+ */
+ const COMPANY_LAST_COMMA_FIRST = 'CompanyLastCommaFirst';
+
+ /**
+ * File as mapping for "company last name first name".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const COMPANY_LAST_FIRST = 'CompanyLastFirst';
+
+ /**
+ * File as mapping for "company last name first name".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const COMPANY_LAST_SPACE_FIRST = 'CompanyLastSpaceFirst';
+
+ /**
+ * File as mapping for "display name".
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DISPLAY_NAME = 'DisplayName';
+
+ /**
+ * File as mapping to use when no mapping is defined.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EMPTY_MAPPING = 'Empty';
+
+ /**
+ * File as mapping for "first name".
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FIRST_NAME = 'FirstName';
+
+ /**
+ * File as mapping for "first name last name".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FIRST_SPACE_LAST = 'FirstSpaceLast';
+
+ /**
+ * File as mapping for "last name, first name".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST_COMMA_FIRST = 'LastCommaFirst';
+
+ /**
+ * File as mapping for "last name, first name company".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST_COMMA_FIRST_COMPANY = 'LastCommaFirstCompany';
+
+ /**
+ * File as mapping for "last name first name".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST_FIRST = 'LastFirst';
+
+ /**
+ * File as mapping for "last name first name company".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST_FIRST_COMPANY = 'LastFirstCompany';
+
+ /**
+ * File as mapping for "last name first name middle name suffix".
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const LAST_FIRST_MIDDLE_SUFFIX = 'LastFirstMiddleSuffix';
+
+ /**
+ * File as mapping for "last name first name suffix".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST_FIRST_SUFFIX = 'LastFirstSuffix';
+
+ /**
+ * File as mapping for "last name".
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const LAST_NAME = 'LastName';
+
+ /**
+ * File as mapping for "last name first name".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST_SPACE_FIRST = 'LastSpaceFirst';
+
+ /**
+ * File as mapping for "last name first name company".
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LAST_SPACE_FIRST_COMPANY = 'LastSpaceFirstCompany';
+
+ /**
+ * File as mapping to use when no mapping is desired.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NONE = 'None';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlagStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlagStatusType.php
new file mode 100644
index 00000000..f9c99a75
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlagStatusType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\FlagStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the flagged status of an item.
+ *
+ * @package php-ews\Enumeration
+ */
+class FlagStatusType extends Enumeration
+{
+ /**
+ * Indicates the complete flag status.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const COMPLETE = 'Complete';
+
+ /**
+ * Indicates the flagged status.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const FLAGGED = 'Flagged';
+
+ /**
+ * Indicates the not-flagged status.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ const NOT_FLAGGED = 'NotFlagged';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlaggedForActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlaggedForActionType.php
new file mode 100644
index 00000000..e3599810
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FlaggedForActionType.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\FlaggedForActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the flag for action value that must appear on incoming messages in
+ * order for the condition or exception to apply.
+ *
+ * @package php-ews\Enumeration
+ */
+class FlaggedForActionType extends Enumeration
+{
+ /**
+ * Indicates that the message may contain any flag.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ANY = 'Any';
+
+ /**
+ * Indicates that the message has been flagged for a call.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CALL = 'Call';
+
+ /**
+ * Indicates that the message is not to be forwarded.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DO_NOT_FORWARD = 'DoNotForward';
+
+ /**
+ * Indicates that the message has been flagged for a follow up.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FOLLOW_UP = 'FollowUp';
+
+ /**
+ * Indicates that the message is to be forwarded.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FORWARD = 'Forward';
+
+ /**
+ * Indicates that the message has been flagged as FYI.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FYI = 'FYI';
+
+ /**
+ * Indicates that the message does not require a response.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NO_RESPONSE_NECESSARY = 'NoResponseNecessary';
+
+ /**
+ * Indicates that the message is to be read.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const READ = 'Read';
+
+ /**
+ * Indicates that the message needs a reply.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const REPLY = 'Reply';
+
+ /**
+ * Indicates that the message needs a reply to all recipients.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const REPLY_TO_ALL = 'ReplyToAll';
+
+ /**
+ * Indicates that the message has been flagged for review.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const REVIEW = 'Review';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FolderQueryTraversalType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FolderQueryTraversalType.php
new file mode 100644
index 00000000..5cb80a62
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FolderQueryTraversalType.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\FolderQueryTraversalType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of sub-tree traversal for an operation.
+ *
+ * @package php-ews\Enumeration
+ */
+class FolderQueryTraversalType extends Enumeration
+{
+ /**
+ * Consider both direct children as well as all subfolders contained within
+ * those children as well as the children's children, etc.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DEEP = 'Deep';
+
+ /**
+ * Consider only folders that are direct children of the parent folder(s) in
+ * question.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SHALLOW = 'Shallow';
+
+ /**
+ * Consider only those items that are soft deleted from the parent folders
+ * specified.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SOFT_DELETED = 'SoftDeleted';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FreeBusyViewType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FreeBusyViewType.php
new file mode 100644
index 00000000..c45b72ed
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/FreeBusyViewType.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\FreeBusyViewType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the type of free/busy information returned in the response.
+ *
+ * @package php-ews\Enumeration
+ */
+class FreeBusyViewType extends Enumeration
+{
+ /**
+ * Represents the legacy status information: free, busy, tentative, and OOF;
+ * the start/end times of the appointments; and various properties of the
+ * appointment such as subject, location, and importance.
+ *
+ * This requested view will return the maximum amount of information for
+ * which the requesting user is privileged. If merged free/busy information
+ * only is available, as with requesting information for users in a
+ * Microsoft Exchange Server 2003 forest, MergedOnly will be returned.
+ * Otherwise, FreeBusy or Detailed will be returned.
+ *
+ * If Detailed is specified for a distribution list, the free/busy
+ * information for the members of the list is merged, and MergedOnly is
+ * returned.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DETAILED = 'Detailed';
+
+ /**
+ * Represents all the properties in Detailed with a stream of merged
+ * free/busy availability information.
+ *
+ * If only merged free/busy information is available, for example if the
+ * mailbox exists on a computer running Exchange 2003, MergedOnly will be
+ * returned. Otherwise, FreeBusyMerged or DetailedMerged will be returned.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DETAILED_MERGED = 'DetailedMerged';
+
+ /**
+ * Represents the legacy status information: free, busy, tentative, and OOF.
+ *
+ * This also includes the start/end times of the appointments. This view is
+ * richer than the legacy free/busy view because individual meeting start
+ * and end times are provided instead of an aggregated free/busy stream.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FREE_BUSY = 'FreeBusy';
+
+ /**
+ * Represents all the properties in FreeBusy with a stream of merged
+ * free/busy availability information.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FREE_BUSY_MERGED = 'FreeBusyMerged';
+
+ /**
+ * Represents an aggregated free/busy stream.
+ *
+ * In cross-forest scenarios in which the target user in one forest does not
+ * have an Availability service configured, the Availability service of the
+ * requester retrieves the target user’s free/busy information from the
+ * free/busy public folder. Because public folders only store free/busy
+ * information in merged form, MergedOnly is the only available information.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MERGED_ONLY = 'MergedOnly';
+
+ /**
+ * This value is not valid for requests but is valid for responses.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NONE = 'None';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldActionType.php
new file mode 100644
index 00000000..788da5ab
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldActionType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\HoldActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of action for a mailbox hold.
+ *
+ * @package php-ews\Enumeration
+ */
+class HoldActionType extends Enumeration
+{
+ /**
+ * Indicates that a mailbox hold will be created.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CREATE = 'Create';
+
+ /**
+ * Indicates that a mailbox hold will be removed.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const REMOVE = 'Remove';
+
+ /**
+ * Indicates that a mailbox hold will be updated.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const UPDATE = 'Update';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldStatusType.php
new file mode 100644
index 00000000..b1ec1285
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/HoldStatusType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\HoldStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the hold status for a mailbox.
+ *
+ * @package php-ews\Enumeration
+ */
+class HoldStatusType extends Enumeration
+{
+ /**
+ * Indicates that the hold on a mailbox has failed.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const FAILED = 'Failed';
+
+ /**
+ * Indicates that the mailbox is not on hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NOT_ON_HOLD = 'NotOnHold';
+
+ /**
+ * Indicates that the mailbox is on hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ON_HOLD = 'OnHold';
+
+ /**
+ * Indicates that the mailbox is on a partial hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PARTIAL_HOLD = 'PartialHold';
+
+ /**
+ * Indicates that a hold on the mailbox is pending.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PENDING = 'Pending';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IdFormatType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IdFormatType.php
new file mode 100644
index 00000000..401b18ec
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IdFormatType.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\IdFormatType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the source format of the Id to be converted or the format of the Id
+ * after conversion.
+ *
+ * @package php-ews\Enumeration
+ */
+class IdFormatType extends Enumeration
+{
+ /**
+ * Describes MAPI identifiers, as in the PR_ENTRYID property.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ENTRY_ID = 'EntryId';
+
+ /**
+ * Describes identifiers that are produced by Exchange Web Services starting
+ * with Exchange 2007 SP1.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const EWS_ID = 'EwsId';
+
+ /**
+ * Describes identifiers that are produced by Exchange Web Services in the
+ * initial release version of Exchange 2007.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const EWS_LEGACY_ID = 'EwsLegacyId';
+
+ /**
+ * Describes a hexadecimal-encoded representation of the PR_ENTRYID
+ * property.
+ *
+ * This is the format of availability calendar event identifiers.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const HEX_ENTRY_ID = 'HexEntryId';
+
+ /**
+ * Describes a Microsoft Office Outlook Web Access identifier.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const OWA_ID = 'OwaId';
+
+ /**
+ * Describes Exchange store identifiers.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const STORE_ID = 'StoreId';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImAddressKeyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImAddressKeyType.php
new file mode 100644
index 00000000..00da9005
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImAddressKeyType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ImAddressKeyType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the key for an instant messenger address.
+ *
+ * @package php-ews\Enumeration
+ */
+class ImAddressKeyType extends Enumeration
+{
+ /**
+ * Instant messenger key for instant messenger address one.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IM_ADDRESS_1 = 'ImAddress1';
+
+ /**
+ * Instant messenger key for instant messenger address two.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IM_ADDRESS_2 = 'ImAddress2';
+
+ /**
+ * Instant messenger key for instant messenger address three.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IM_ADDRESS_3 = 'ImAddress3';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImportanceChoicesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImportanceChoicesType.php
new file mode 100644
index 00000000..03ffdd89
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ImportanceChoicesType.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ImportanceChoicesType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes the importance of an item or the aggregated importance of all items
+ * in a conversation in the current folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class ImportanceChoicesType extends Enumeration
+{
+ /**
+ * High importance level.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HIGH = 'High';
+
+ /**
+ * Low importance level.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LOW = 'Low';
+
+ /**
+ * Normal importance level.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NORMAL = 'Normal';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IndexBasePointType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IndexBasePointType.php
new file mode 100644
index 00000000..47f24132
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/IndexBasePointType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\IndexBasePointType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines whether a page of items or conversations will start from the
+ * beginning or the end of a set.
+ *
+ * @package php-ews\Enumeration
+ */
+class IndexBasePointType extends Enumeration
+{
+ /**
+ * The paged view starts at the beginning of the found conversation or item
+ * set.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BEGINNING = 'Beginning';
+
+ /**
+ * The paged view starts at the end of the found conversation or item set.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const END = 'End';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/InvalidRecipientResponseCodeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/InvalidRecipientResponseCodeType.php
new file mode 100644
index 00000000..81e26b1c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/InvalidRecipientResponseCodeType.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\InvalidRecipientResponseCodeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Provides information about why a recipient is invalid.
+ *
+ * @package php-ews\Enumeration
+ */
+class InvalidRecipientResponseCodeType extends Enumeration
+{
+ /**
+ * Indicates that there was a problem obtaining a security token from the
+ * token server.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CANNOT_OBTAIN_TOKEN_FROM_STS = 'CannotObtainTokenFromSTS';
+
+ /**
+ * Indicates that the error is not specified by another error response code.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const OTHER = 'OtherError';
+
+ /**
+ * Indicates that the secure token service that is used by the specified
+ * recipient is unknown.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECIPIENT_ORG_FEDERATED_UNKNOWN_TOKEN_ISSUER = 'RecipientOrganizationFederatedWithUnknownTokenIssuer';
+
+ /**
+ * Indicates that a sharing relationship is not available with the
+ * organization specified in the recipient's SMTP e-mail address.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECIPIENT_ORG_NOT_FEDERATED = 'RecipientOrganizationNotFederated';
+
+ /**
+ * Indicates that the system administrator has set a system policy that
+ * blocks sharing with the specified recipient.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SYSTEM_POLICY_BLOCKS_SHARING_WITH_RECIPIENT = 'SystemPolicyBlocksSharingWithThisRecipient';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemClassType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemClassType.php
new file mode 100644
index 00000000..675ae6eb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemClassType.php
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ItemClassType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the message class of an item.
+ *
+ * @package php-ews\Enumeration
+ */
+class ItemClassType extends Enumeration
+{
+ /**
+ * Class used to identify a form for journal entries.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACTIVITY = 'IPM.Activity';
+
+ /**
+ * Class used to identify a form for appointments.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const APPOINTMENT = 'IPM.Appointment';
+
+ /**
+ * Class used to identify a form for contacts.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACT = 'IPM.Contact';
+
+ /**
+ * Class used to identify a form for distribution lists.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DISTRIBUTION_LIST = 'IPM.DistList';
+
+ /**
+ * Class used to identify a form for documents.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DOCUMENT = 'IPM.Document';
+
+ /**
+ * Class used to identify a form for items for which the specified form
+ * can not be found.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IPM = 'IPM';
+
+ /**
+ * Class used to identify a form for e-mail messages.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOTE = 'IPM.Note';
+
+ /**
+ * Class used to identify a form for reports from the Internet Mail Connect
+ * (the Exchange Server gateway to the Internet).
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOTE_IMC_NOTIFICATION = 'IPM.Note.IMC.Notification';
+
+ /**
+ * Class used to identify a form for out-of-office templates.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOTE_RULES_OOF_TEMPLATE_MICROSOFT = 'IPM.Note.Rules.Oof.Template.Microsoft';
+
+ /**
+ * Class used to identify a form for editing rule reply templates.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOTE_RULES_REPLY_TEMPLATE_MICROSOFT = 'IPM.Note.Rules.ReplyTemplate.Microsoft';
+
+ /**
+ * Class used to identify a form for encrypted notes to other people.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOTE_SECURE = 'IPM.Note.Secure';
+
+ /**
+ * Class used to identify a form for digitally signed notes to other people.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOTE_SECURE_SIGN = 'IPM.Note.Secure.Sign';
+
+ /**
+ * Class used to identify a form for the exception item of a recurrence
+ * series.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OLE_CLASS = 'IPM.OLE.Class';
+
+ /**
+ * Class used to identify a form for recalling sent messages from recipient
+ * Inboxes.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OUTLOOK_RECALL = 'IPM.Outlook.Recall';
+
+ /**
+ * Class used to identify a form for posting notes in a folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const POST = 'IPM.Post';
+
+ /**
+ * Class used to identify a form for message recall reports.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECALL_REPORT = 'IPM.Recall.Report';
+
+ /**
+ * Class used to identify a form for remote Mail message headers.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const REMOTE = 'IPM.Remote';
+
+ /**
+ * Class used to identify a form for reporting item status.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const REPORT = 'IPM.Report';
+
+ /**
+ * Class used to identify a form for resending a failed message.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESEND = 'IPM.Resend';
+
+ /**
+ * Class used to identify a form for meeting cancellations.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SCHEDULE_MEETING_CANCELED = 'IPM.Schedule.Meeting.Canceled';
+
+ /**
+ * Class used to identify a form for meeting requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SCHEDULE_MEETING_REQUEST = 'IPM.Schedule.Meeting.Request';
+
+ /**
+ * Class used to identify a form for responses to decline meeting requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SCHEDULE_MEETING_RESP_NEG = 'IPM.Schedule.Meeting.Resp.Neg';
+
+ /**
+ * Class used to identify a form for responses to accept meeting requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SCHEDULE_MEETING_RESP_POS = 'IPM.Schedule.Meeting.Resp.Pos';
+
+ /**
+ * Class used to identify a form for responses to tentatively accept meeting
+ * requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SCHEDULE_MEETING_RESP_TENT = 'IPM.Schedule.Meeting.Resp.Tent';
+
+ /**
+ * Class used to identify a form for creating notes.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const STICKY_NOTE = 'IPM.StickyNote';
+
+ /**
+ * Class used to identify a form for tasks.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK = 'IPM.Task';
+
+ /**
+ * Class used to identify a form for task requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_REQUEST = 'IPM.TaskRequest';
+
+ /**
+ * Class used to identify a form for responses to accept task requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_REQUEST_ACCEPT = 'IPM.TaskRequest.Accept';
+
+ /**
+ * Class used to identify a form for responses to decline task requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_REQUEST_DECLINE = 'IPM.TaskRequest.Decline';
+
+ /**
+ * Class used to identify a form for updates to requested tasks.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_REQUEST_UPDATE = 'IPM.TaskRequest.Update';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemQueryTraversalType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemQueryTraversalType.php
new file mode 100644
index 00000000..db05066d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ItemQueryTraversalType.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ItemQueryTraversalType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Types of sub-tree traversal for deletion and enumeration.
+ *
+ * @package php-ews\Enumeration
+ */
+class ItemQueryTraversalType extends Enumeration
+{
+ /**
+ * Returns only the identities of associated items in the folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ASSOCIATED = 'Associated';
+
+ /**
+ * Returns only the identities of items in the folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SHALLOW = 'Shallow';
+
+ /**
+ * Returns only the identities of items that are in a folder's dumpster.
+ *
+ * Note that a soft-deleted traversal combined with a search restriction
+ * will result in zero items returned even if there are items that match the
+ * search criteria.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SOFT_DELETED = 'SoftDeleted';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LegacyFreeBusyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LegacyFreeBusyType.php
new file mode 100644
index 00000000..e13df976
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LegacyFreeBusyType.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\LegacyFreeBusyType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the intended status for a calendar item that is associated with a
+ * meeting request.
+ *
+ * @package php-ews\Enumeration
+ */
+class LegacyFreeBusyType extends Enumeration
+{
+ /**
+ * The calendar item represents busy time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BUSY = 'Busy';
+
+ /**
+ * The calendar item represents free time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FREE = 'Free';
+
+ /**
+ * The calendar item's status is not defined.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_DATA = 'NoData';
+
+ /**
+ * The calendar item represents time out of the office.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OUT_OF_OFFICE = 'OOF';
+
+ /**
+ * The calendar item represents tentatively busy time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TENTATIVE = 'Tentative';
+
+ /**
+ * The calendar item represents time working off site.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WORKING_ELSEWHERE = 'WorkingElsewhere';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LocationSourceType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LocationSourceType.php
new file mode 100644
index 00000000..77cc4d5a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/LocationSourceType.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\LocationSourceType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies information about the origin of an associated postal address, for
+ * example, a contact or a telephone book.
+ *
+ * @package php-ews\Enumeration
+ */
+class LocationSourceType extends Enumeration
+{
+ /**
+ * The information was obtained from a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONTACT = 'Contact';
+
+ /**
+ * The information was obtained from the device.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DEVICE = 'Device';
+
+ /**
+ * The information was obtained from location services.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const LOCATION_SERVICES = 'LocationServices';
+
+ /**
+ * There is no location source.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * The information was obtained from phonebook services.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PHONEBOOK_SERVICES = 'PhonebookServices';
+
+ /**
+ * The information was obtained from a resource.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const RESOURCE = 'Resource';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailTipTypes.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailTipTypes.php
new file mode 100644
index 00000000..2be635d2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailTipTypes.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MailTipTypes.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the types of mail tips requested from the service.
+ *
+ * @package php-ews\Enumeration
+ */
+class MailTipTypes extends Enumeration
+{
+ /**
+ * Represents all available mail tips.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ALL = 'All';
+
+ /**
+ * Represents a custom mail tip.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CUSTOM_MAIL_TIP = 'CustomMailTip';
+
+ /**
+ * Indicates whether delivery restrictions will prevent the sender's message
+ * from reaching the recipient.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DELIVERY_RESTRICTION = 'DeliveryRestriction';
+
+ /**
+ * Represents the count of external members.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXTERNAL_MEMBER_COUNT = 'ExternalMemberCount';
+
+ /**
+ * Indicates whether the recipient is invalid.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_RECIPIENT = 'InvalidRecipient';
+
+ /**
+ * Represents the status for a mailbox that is full.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MAILBOX_FULL_STATUS = 'MailboxFullStatus';
+
+ /**
+ * Represents the maximum message size a recipient can accept.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MAX_MESSAGE_SIZE = 'MaxMessageSize';
+
+ /**
+ * Indicates whether the sender's message will be reviewed by a moderator.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MODERATION_STATUS = 'ModerationStatus';
+
+ /**
+ * Represents the Out of Office (OOF) message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const OUT_OF_OFFICE_MESSAGE = 'OutOfOfficeMessage';
+
+ /**
+ * Represents the count of all members.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const TOTAL_MEMBER_COUNT = 'TotalMemberCount';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxSearchLocationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxSearchLocationType.php
new file mode 100644
index 00000000..3429a841
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxSearchLocationType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MailboxSearchLocationType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines whether a search or fetch for a conversation should span either the
+ * primary mailbox, archive mailbox, or both the primary and archive mailbox.
+ *
+ * @package php-ews\Enumeration
+ */
+class MailboxSearchLocationType extends Enumeration
+{
+ /**
+ * Indicates a scope that targets both the primary mailbox and archive
+ * mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ALL = 'All';
+
+ /**
+ * Indicates a scope that targets the archive mailbox for a user.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ARCHIVE = 'ArchiveOnly';
+
+ /**
+ * Indicates a scope that targets the primary mailbox for a user.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PRIMARY = 'PrimaryOnly';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxTypeType.php
new file mode 100644
index 00000000..e2a080c4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MailboxTypeType.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MailboxTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the type of mailbox that is represented by an e-mail address.
+ *
+ * @package php-ews\Enumeration
+ */
+class MailboxTypeType extends Enumeration
+{
+ /**
+ * Represents a contact in a user's mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACT = 'Contact';
+
+ /**
+ * Represents a mail-enabled Active Directory object.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAILBOX = 'Mailbox';
+
+ /**
+ * Represents a one-off member of a personal distribution list.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ONE_OFF = 'OneOff';
+
+ /**
+ * Represents a private distribution list in a user's mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PRIVATE_DISTRIBUTION_LIST = 'PrivateDL';
+
+ /**
+ * Represents a public distribution list.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PUBLIC_DISTRIBUTION_LIST = 'PublicDL';
+
+ /**
+ * Represents a public folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PUBLIC_FOLDER = 'PublicFolder';
+
+ /**
+ * Represents an unknown type of mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNKNOWN = 'Unknown';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MapiPropertyTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MapiPropertyTypeType.php
new file mode 100644
index 00000000..27850f8a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MapiPropertyTypeType.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MapiPropertyTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the property type of a property tag.
+ *
+ * @package php-ews\Enumeration
+ */
+class MapiPropertyTypeType extends Enumeration
+{
+ /**
+ * A double value that is interpreted as a date and time. The integer part
+ * is the date and the fraction part is the time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const APPLICATION_TIME = 'ApplicationTime';
+
+ /**
+ * An array of double values that are interpreted as a date and time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const APPLICATION_TIME_ARRAY = 'ApplicationTimeArray';
+
+ /**
+ * A Base64-encoded binary value.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BINARY = 'Binary';
+
+ /**
+ * An array of Base64-encoded binary values.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BINARY_ARRAY = 'BinaryArray';
+
+ /**
+ * A Boolean true or false.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BOOLEAN = 'Boolean';
+
+ /**
+ * A GUID string.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CLSID = 'CLSID';
+
+ /**
+ * An array of GUID strings.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CLSID_ARRAY = 'CLSIDArray';
+
+ /**
+ * A 64-bit integer that is interpreted as the number of cents.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CURRENCY = 'Currency';
+
+ /**
+ * An array of 64-bit integers that are interpreted as the number of cents.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CURRENCY_ARRAY = 'CurrencyArray';
+
+ /**
+ * A 64-bit floating-point value.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DOUBLE = 'Double';
+
+ /**
+ * An array of 64-bit floating-point values.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DOUBLE_ARRAY = 'DoubleArray';
+
+ /**
+ * SCODE value; 32-bit unsigned integer.
+ *
+ * Not used for restrictions or for getting/setting values. This exists only
+ * for reporting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ERROR = 'Error';
+
+ /**
+ * A 32-bit floating-point value.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FLOAT = 'Float';
+
+ /**
+ * An array of 32-bit floating-point values.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FLOAT_ARRAY = 'FloatArray';
+
+ /**
+ * A signed 32-bit (Int32) integer.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INTEGER = 'Integer';
+
+ /**
+ * An array of signed 32-bit (Int32) integers.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INTEGER_ARRAY = 'IntegerArray';
+
+ /**
+ * A signed or unsigned 64-bit (Int64) integer.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LONG = 'Long';
+
+ /**
+ * An array of signed or unsigned 64-bit (Int64) integers.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LONG_ARRAY = 'LongArray';
+
+ /**
+ * Indicates no property value.
+ *
+ * Not used for restrictions or for getting/setting values. This exists only
+ * for reporting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NULL_TYPE = 'Null';
+
+ /**
+ * A pointer to an object that implements the IUnknown interface.
+ *
+ * Not used for restrictions or for getting/setting values. This exists only
+ * for reporting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OBJECT = 'Object';
+
+ /**
+ * An array of pointers to objects that implement the IUnknown interface.
+ *
+ * Not used for restrictions or for getting/setting values. This exists only
+ * for reporting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OBJECT_ARRAY = 'ObjectArray';
+
+ /**
+ * A signed 16-bit integer.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SHORT = 'Short';
+
+ /**
+ * An array of signed 16-bit integers.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SHORT_ARRAY = 'ShortArray';
+
+ /**
+ * A 64-bit integer data and time value in the form of a FILETIME structure.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SYSTEM_TIME = 'SystemTime';
+
+ /**
+ * An array of 64-bit integer data and time values in the form of a FILETIME
+ * structure.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SYSTEM_TIME_ARRAY = 'SystemTimeArray';
+
+ /**
+ * A Unicode string.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const STRING = 'String';
+
+ /**
+ * An array of Unicode strings.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const STRING_ARRAY = 'StringArray';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingAttendeeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingAttendeeType.php
new file mode 100644
index 00000000..27deee34
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingAttendeeType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MeetingAttendeeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the type of attendee that is identified in the Email element.
+ *
+ * @package php-ews\Enumeration
+ */
+class MeetingAttendeeType extends Enumeration
+{
+ /**
+ * A mailbox user who is an optional attendee to the meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OPTIONAL = 'Optional';
+
+ /**
+ * The mailbox user and attendee who created the calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ORGANIZER = 'Organizer';
+
+ /**
+ * A mailbox user who is a required attendee to the meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const REQUIRED = 'Required';
+
+ /**
+ * A resource such as a TV or projector that is scheduled for use in the meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESOURCE = 'Resource';
+
+ /**
+ * A mailbox entity that represents a room resource used for the meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ROOM = 'Room';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingRequestTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingRequestTypeType.php
new file mode 100644
index 00000000..11ee46d6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MeetingRequestTypeType.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MeetingRequestTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes the type of a meeting request.
+ *
+ * @package php-ews\Enumeration
+ */
+class MeetingRequestTypeType extends Enumeration
+{
+ /**
+ * Identifies the meeting request as a full update to an existing request.
+ *
+ * A full update has updated time and informational content.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FULL_UPDATE = 'FullUpdate';
+
+ /**
+ * Identifies the meeting request as only containing updated informational
+ * content.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INFORMATIONAL_UPDATE = 'InformationalUpdate';
+
+ /**
+ * Identifies the meeting request as a new meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NEW_MEETING_REQUEST = 'NewMeetingRequest';
+
+ /**
+ * Indicates that the meeting request type is not defined.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * Identifies the meeting request as outdated.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OUTDATED = 'Outdated';
+
+ /**
+ * Indicates that the meeting request belongs to a principal who has
+ * forwarded meeting messages to a delegate and has his copies marked as
+ * informational.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PRINCIPAL_WANTS_COPY = 'PrincipalWantsCopy';
+
+ /**
+ * Identifies the meeting request as a silent update to an existing meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SILENT_UPDATE = 'SilentUpdate';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MemberStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MemberStatusType.php
new file mode 100644
index 00000000..7a5d0cd7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MemberStatusType.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MemberStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the status of a distribution list member on the server.
+ *
+ * @package php-ews\Enumeration
+ */
+class MemberStatusType extends Enumeration
+{
+ /**
+ * Referenced object is not available.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DEMOTED = 'Demoted';
+
+ /**
+ * Member information in a distribution list is in sync with the referenced
+ * object.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NORMAL = 'Normal';
+
+ /**
+ * Member information is invalid or unrecognized.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNRECOGNIZED = 'Unrecognized';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageDispositionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageDispositionType.php
new file mode 100644
index 00000000..56a40477
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageDispositionType.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MessageDispositionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes how an e-mail message will be handled after it is created.
+ *
+ * @package php-ews\Enumeration
+ */
+class MessageDispositionType extends Enumeration
+{
+ /**
+ * The message item is saved in the folder that is specified by the
+ * SavedItemFolderId element.
+ *
+ * Messages can be sent later by using the SendItem operation. An item
+ * identifier is returned in the response. Item identifiers are not returned
+ * for any item types except for message items. This includes response
+ * objects.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SAVE_ONLY = 'SaveOnly';
+
+ /**
+ * The item is sent and a copy is saved in the folder that is identified by
+ * the SavedItemFolderId element.
+ *
+ * An item identifier is not returned in the response.
+ *
+ * Meeting requests are not saved to the folder that is identified by the
+ * SavedItemFolderId property. For calendaring, only the save location for
+ * calendar items can be specified by the SavedItemFolderId property. You
+ * cannot control where a meeting request item is saved. Only the associated
+ * calendar items are copied and saved into the folder that is identified by
+ * the SavedItemFolderId property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_AND_SAVE_COPY = 'SendAndSaveCopy';
+
+ /**
+ * The item is sent but no copy is saved in the Sent Items folder.
+ *
+ * An item identifier is not returned in the response.
+ *
+ * CreateItem does not support delegate access when the SendOnly option is
+ * used because a destination folder cannot be specified with this option.
+ * The workaround is to create the item, get the item identifier, and then
+ * use the SendItem operation to send the item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_ONLY = 'SendOnly';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingDeliveryStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingDeliveryStatusType.php
new file mode 100644
index 00000000..5965e5cf
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingDeliveryStatusType.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MessageTrackingDeliveryStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the status for a message.
+ *
+ * @package php-ews\Enumeration
+ */
+class MessageTrackingDeliveryStatusType extends Enumeration
+{
+ /**
+ * Specifies that the message was delivered to all of the specified
+ * recipients.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DELIVERED = 'Delivered';
+
+ /**
+ * Specifies that the message is waiting for approval from a moderator.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PENDING = 'Pending';
+
+ /**
+ * Specifies that the message was delivered and read by the recipients.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const READ = 'Read';
+
+ /**
+ * Specifies that the message was transferred to a server outside the search
+ * scope.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const TRANSFERRED = 'Transferred';
+
+ /**
+ * Specifies that a message was not delivered.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNSUCCESSFUL = 'Unsuccessful';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingEventDescriptionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingEventDescriptionType.php
new file mode 100644
index 00000000..5ed814bb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingEventDescriptionType.php
@@ -0,0 +1,254 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MessageTrackingEventDescriptionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Class description...
+ *
+ * @package php-ews\Enumeration
+ */
+class MessageTrackingEventDescriptionType extends Enumeration
+{
+ /**
+ * Indicates the event is for a message that has been approved.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const APPROVED_MODERATION = 'ApprovedModeration';
+
+ /**
+ * Indicates the event is for a message that has been delayed after
+ * transferring to a partner organization.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DELAYED_AFTER_TRANSFER_TO_PARTNER_ORG = 'DelayedAfterTransferToPartnerOrg';
+
+ /**
+ * Indicates the event is for a delivered message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DELIVERED = 'Delivered';
+
+ /**
+ * Indicates the event is for an expanded message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXPANDED = 'Expanded';
+
+ /**
+ * Indicates the event is for a message that failed with a general error.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FAILED_GENERAL = 'FailedGeneral';
+
+ /**
+ * Indicates the event is for a message that failed moderation.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FAILED_MODERATION = 'FailedModeration';
+
+ /**
+ * Indicates the event is for a message that failed transport rules.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FAILED_TRANSPORT_RULES = 'FailedTransportRules';
+
+ /**
+ * Indicates the event is for a forwarded message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FORWARDED = 'Forwarded';
+
+ /**
+ * Indicates the event is for a message that was deferred.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MESSAGE_DEFER = 'MessageDefer';
+
+ /**
+ * Indicates the event is for a message that was moved by an inbox rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MOVED_TO_FOLDER_BY_INBOX_RULE = 'MovedToFolderByInboxRule';
+
+ /**
+ * Indicates the event is for a not read message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NOT_READ = 'NotRead';
+
+ /**
+ * Indicates the event is for a pending message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PENDING = 'Pending';
+
+ /**
+ * Indicates the event is for a message pending moderation.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PENDING_MODERATION = 'PendingModeration';
+
+ /**
+ * Indicates the event is for a message that was queued to be retried.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const QUEUE_RETRY = 'QueueRetry';
+
+ /**
+ * Indicates the event is for a queued to be retried without a time.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const QUEUE_RETRY_NO_RETRY_TIME = 'QueueRetryNoRetryTime';
+
+ /**
+ * Indicates the event is for a read message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const READ = 'Read';
+
+ /**
+ * Indicates the event is for a resolved message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RESOLVED = 'Resolved';
+
+ /**
+ * Indicates the event is for a message that was CCed by a rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RULES_CC = 'RulesCc';
+
+ /**
+ * Indicates the event is for a message that was received via SMTP.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SMTP_RECEIVE = 'SmtpReceive';
+
+ /**
+ * Indicates the event is for a message that was sent via SMTP.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SMTP_SEND = 'SmtpSend';
+
+ /**
+ * Indicates the event is for a message that was sent cross forest via SMTP.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SMTP_SEND_CROSS_FOREST = 'SmtpSendCrossForest';
+
+ /**
+ * Indicates the event is for a message that was sent cross site via SMTP.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SMTP_SEND_CROSS_SITE = 'SmtpSendCrossSite';
+
+ /**
+ * Indicates the event is for a submitted message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SUBMITTED = 'Submitted';
+
+ /**
+ * Indicates the event is for a message that was transferred to a foreign
+ * organization.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const TRANSFERRED_TO_FOREIGN_ORG = 'TransferredToForeignOrg';
+
+ /**
+ * Indicates the event is for a message that was transferred to a legacy
+ * exchange server.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const TRANSFERRED_TO_LEGACY_EXCHANGE_SERVER = 'TransferredToLegacyExchangeServer';
+
+ /**
+ * Indicates the event is for a message that was transferred to a partner
+ * organization.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const TRANSFERRED_TO_PARTNER_ORG = 'TransferredToPartnerOrg';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingReportTemplateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingReportTemplateType.php
new file mode 100644
index 00000000..9cd1391b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MessageTrackingReportTemplateType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MessageTrackingReportTemplateType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the type of report to get.
+ *
+ * @package php-ews\Enumeration
+ */
+class MessageTrackingReportTemplateType extends Enumeration
+{
+ /**
+ * Specifies that for a single recipient, the report will display a full
+ * history of the events that occurred.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECIPIENT_PATH = 'RecipientPath';
+
+ /**
+ * Specifies that the report will display all the recipients of the message
+ * and the delivery status of the message to each recipient.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SUMMARY = 'Summary';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MonthNamesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MonthNamesType.php
new file mode 100644
index 00000000..e6d6e985
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/MonthNamesType.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\MonthNamesType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes the month when a yearly recurring item occurs.
+ *
+ * @package php-ews\Enumeration
+ */
+class MonthNamesType extends Enumeration
+{
+ /**
+ * Text value for the month of April.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const APRIL = 'April';
+
+ /**
+ * Text value for the month of August.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const AUGUST = 'August';
+
+ /**
+ * Text value for the month of February.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FEBRUARY = 'February';
+
+ /**
+ * Text value for the month of December.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DECEMBER = 'December';
+
+ /**
+ * Text value for the month of January.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const JANUARY = 'January';
+
+ /**
+ * Text value for the month of July.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const JULY = 'July';
+
+ /**
+ * Text value for the month of June.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const JUNE = 'June';
+
+ /**
+ * Text value for the month of March.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MARCH = 'March';
+
+ /**
+ * Text value for the month of May.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAY = 'May';
+
+ /**
+ * Text value for the month of November.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOVEMBER = 'November';
+
+ /**
+ * Text value for the month of October.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OCTOBER = 'October';
+
+ /**
+ * Text value for the month of September.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEPTEMBER = 'September';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/NotificationEventTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/NotificationEventTypeType.php
new file mode 100644
index 00000000..5c9d7185
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/NotificationEventTypeType.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\NotificationEventTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of event a notification is for.
+ *
+ * @package php-ews\Enumeration
+ */
+class NotificationEventTypeType extends Enumeration
+{
+ /**
+ * Indicates the notification is for an item copied event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const COPIED_EVENT = 'CopiedEvent';
+
+ /**
+ * Indicates the notification is for an item created event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CREATED_EVENT = 'CreatedEvent';
+
+ /**
+ * Indicates the notification is for an item deleted event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DELETED_EVENT = 'DeletedEvent';
+
+ /**
+ * Indicates the notification is for a free or busy change event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FREE_BUSY_CHANGED_EVENT = 'FreeBusyChangedEvent';
+
+ /**
+ * Indicates the notification is for an item modified event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MODIFIED_EVENT = 'ModifiedEvent';
+
+ /**
+ * Indicates the notification is for an item moved event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MOVED_EVENT = 'MovedEvent';
+
+ /**
+ * Indicates the notification is for a new mail event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NEW_MAIL_EVENT = 'NewMailEvent';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Occurrence.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Occurrence.php
new file mode 100644
index 00000000..712c2657
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Occurrence.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\Occurrence.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the occurrence of the day of the week in a month.
+ *
+ * @package php-ews\Enumeration
+ */
+class Occurrence extends Enumeration
+{
+ /**
+ * The first occurrence of the specified day of the week from the beginning
+ * of the month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const FIRST_FROM_BEGINNING = 1;
+
+ /**
+ * The first occurrence of the specified day of the week from the end of the
+ * month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const FIRST_FROM_END = -1;
+
+ /**
+ * The fourth occurrence of the specified day of the week from the beginning
+ * of the month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const FOURTH_FROM_BEGINNING = 4;
+
+ /**
+ * The fourth occurrence of the specified day of the week from the end of the
+ * month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const FOURTH_FROM_END = -4;
+
+ /**
+ * The second occurrence of the specified day of the week from the beginning
+ * of the month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const SECOND_FROM_BEGINNING = 2;
+
+ /**
+ * The second occurrence of the specified day of the week from the end of
+ * the month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const SECOND_FROM_END = -2;
+
+ /**
+ * The third occurrence of the specified day of the week from the beginning
+ * of the month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const THIRD_FROM_BEGINNING = 3;
+
+ /**
+ * The third occurrence of the specified day of the week from the end of the
+ * month.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ const THIRD_FROM_END = -3;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/OofState.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/OofState.php
new file mode 100644
index 00000000..d038fda9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/OofState.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\OofState.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents a user's Out of Office (OOF) state.
+ *
+ * @package php-ews\Enumeration
+ */
+class OofState extends Enumeration
+{
+ /**
+ * The user's OOF setting is currently disabled.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DISABLED = 'Disabled';
+
+ /**
+ * The user's OOF setting is currently enabled.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ENABLED = 'Enabled';
+
+ /**
+ * The user's OOF setting is scheduled to start at a specific date and end
+ * at another specific date.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SCHEDULED = 'Scheduled';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionActionType.php
new file mode 100644
index 00000000..8afebf4c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionActionType.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PermissionActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Indicates which items in a folder a user has permission to perform an action
+ * on.
+ *
+ * @package php-ews\Enumeration
+ */
+class PermissionActionType extends Enumeration
+{
+ /**
+ * Indicates that the user has permission to perform the action on all items
+ * in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ALL = 'All';
+
+ /**
+ * Indicates that the user does not have permission to perform the action on
+ * items in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * Indicates that the user has permission to perform the action on the items
+ * that the user owns in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const OWNED = 'Owned';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionLevelType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionLevelType.php
new file mode 100644
index 00000000..3b17c190
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionLevelType.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PermissionLevelType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the permission level that a user has on a folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class PermissionLevelType extends Enumeration
+{
+ /**
+ * Indicates that the user can create and read all items in the folder, and
+ * edit and delete only items that the user creates.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const AUTHOR = 'Author';
+
+ /**
+ * Indicates that the user can create items in the folder.
+ *
+ * The contents of the folder do not appear.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const CONTRIBUTOR = 'Contributor';
+
+ /**
+ * Indicates that the user has custom access permissions on the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const CUSTOM = 'Custom';
+
+ /**
+ * Indicates that the user can create, read, edit, and delete all items in
+ * the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const EDITOR = 'Editor';
+
+ /**
+ * Indicates that the user can create and read all items in the folder, and
+ * delete only items that the user creates.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const NON_EDITING_AUTHOR = 'NoneditingAuthor';
+
+ /**
+ * Indicates that the user has no permissions on the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * Indicates that the user can create, read, edit, and delete all items in
+ * the folder, and create subfolders.
+ *
+ * The user is both folder owner and folder contact.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const OWNER = 'Owner';
+
+ /**
+ * Indicates that the user can create and read all items in the folder,
+ * edit and delete only items that the user creates, and create subfolders.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const PUBLISHING_AUTHOR = 'PublishingAuthor';
+
+ /**
+ * Indicates that the user can create, read, edit, and delete all items in
+ * the folder, and create subfolders.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const PUBLISHING_EDITOR = 'PublishingEditor';
+
+ /**
+ * Indicates that the user can read all items in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const REVIEWER = 'Reviewer';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionReadAccessType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionReadAccessType.php
new file mode 100644
index 00000000..a5675009
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PermissionReadAccessType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PermissionReadAccessType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Indicates whether a user has permission to read items within a folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class PermissionReadAccessType extends Enumeration
+{
+ /**
+ * Indicates that the user has permission to read all items in the folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const FULL_DETAILS = 'FullDetails';
+
+ /**
+ * Indicates that the user does not have permission to read items in the
+ * folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const NONE = 'None';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneCallStateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneCallStateType.php
new file mode 100644
index 00000000..e5c4b768
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneCallStateType.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PhoneCallStateType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the current state for a phone call.
+ *
+ * @package php-ews\Enumeration
+ */
+class PhoneCallStateType extends Enumeration
+{
+ /**
+ * The call is in alerting state (phone is ringing).
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ALERTED = 'Alerted';
+
+ /**
+ * The call is in the connected state.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONNECTED = 'Connected';
+
+ /**
+ * The system is dialing this call.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONNECTING = 'Connecting';
+
+ /**
+ * The call is disconnected.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DISCONNECTED = 'Disconnected';
+
+ /**
+ * The call is being forwarded to another destination.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FORWARDING = 'Forwarding';
+
+ /**
+ * Initial call state.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const IDLE = 'Idle';
+
+ /**
+ * The call is inbound.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INCOMING = 'Incoming';
+
+ /**
+ * The call is being transferred to another destination.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const TRANSFERRING = 'Transferring';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneNumberKeyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneNumberKeyType.php
new file mode 100644
index 00000000..908a4ef9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhoneNumberKeyType.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PhoneNumberKeyType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the key for a phone number.
+ *
+ * @package php-ews\Enumeration
+ */
+class PhoneNumberKeyType extends Enumeration
+{
+ /**
+ * Phone number key for assistant phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ASSISTANT_PHONE = 'AssistantPhone';
+
+ /**
+ * Phone number key for business fax number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BUSINESS_FAX = 'BusinessFax';
+
+ /**
+ * Phone number key for business phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BUSINESS_PHONE = 'BusinessPhone';
+
+ /**
+ * Phone number key for second business phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BUSINESS_PHONE_2 = 'BusinessPhone2';
+
+ /**
+ * Phone number key for callback.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALLBACK = 'Callback';
+
+ /**
+ * Phone number key for car phone.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CAR_PHONE = 'CarPhone';
+
+ /**
+ * Phone number key for company main phone.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const COMPANY_MAIN_PHONE = 'CompanyMainPhone';
+
+ /**
+ * Phone number key for home fax number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HOME_FAX = 'HomeFax';
+
+ /**
+ * Phone number key for home phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HOME_PHONE = 'HomePhone';
+
+ /**
+ * Phone number key for second home phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HOME_PHONE_2 = 'HomePhone2';
+
+ /**
+ * Phone number key for ISDN line.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ISDN = 'Isdn';
+
+ /**
+ * Phone number key for mobile phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MOBILE_PHONE = 'MobilePhone';
+
+ /**
+ * Phone number key for other fax number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OTHER_FAX = 'OtherFax';
+
+ /**
+ * Phone number key for other phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OTHER_PHONE = 'OtherTelephone';
+
+ /**
+ * Phone number key for pager.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PAGER = 'Pager';
+
+ /**
+ * Phone number key for primary phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PRIMARY_PHONE = 'PrimaryPhone';
+
+ /**
+ * Phone number key for radio phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RADIO_PHONE = 'RadioPhone';
+
+ /**
+ * Phone number key for telex.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TELEX = 'Telex';
+
+ /**
+ * Phone number key for TTY TTD phone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TTY_TTD_PHONE = 'TtyTtdPhone';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressIndexType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressIndexType.php
new file mode 100644
index 00000000..4f663950
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressIndexType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PhysicalAddressIndexType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the display types for physical addresses.
+ *
+ * @package php-ews\Enumeration
+ */
+class PhysicalAddressIndexType extends Enumeration
+{
+ /**
+ * Address index for business.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BUSINESS = 'Business';
+
+ /**
+ * Address index for home.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HOME = 'Home';
+
+ /**
+ * Address index for none.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * Address index for other.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OTHER = 'Other';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressKeyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressKeyType.php
new file mode 100644
index 00000000..7239a1fb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PhysicalAddressKeyType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PhysicalAddressKeyType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the key for a physical address.
+ *
+ * @package php-ews\Enumeration
+ */
+class PhysicalAddressKeyType extends Enumeration
+{
+ /**
+ * Indicates that the address is a business.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BUSINESS = 'Business';
+
+ /**
+ * Indicates that the address is a home.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const HOME = 'Home';
+
+ /**
+ * Indicates that the address is another type of location.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OTHER = 'Other';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PreviewItemBaseShapeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PreviewItemBaseShapeType.php
new file mode 100644
index 00000000..ecac039d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/PreviewItemBaseShapeType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\PreviewItemBaseShapeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of preview to be returned for an item.
+ *
+ * @package php-ews\Enumeration
+ */
+class PreviewItemBaseShapeType extends Enumeration
+{
+ /**
+ * Indicates that only selected properties are shown.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const COMPACT = 'Compact';
+
+ /**
+ * Indicates that all properties are shown.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DEFAULT_SHAPE = 'Default';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderActionType.php
new file mode 100644
index 00000000..cd23c25d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderActionType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ReminderActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the action to take on a reminder.
+ *
+ * @package php-ews\Enumeration
+ */
+class ReminderActionType extends Enumeration
+{
+ /**
+ * Dismiss the reminder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DISMISS = 'Dismiss';
+
+ /**
+ * Snooze the reminder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SNOOZE = 'Snooze';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderGroup.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderGroup.php
new file mode 100644
index 00000000..f89b08bb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ReminderGroup.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ReminderGroup.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines whether the reminder is for a calendar item or a task.
+ *
+ * @package php-ews\Enumeration
+ */
+class ReminderGroup extends Enumeration
+{
+ /**
+ * Specifies that the reminder is for a calendar item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR = 'Calendar';
+
+ /**
+ * Specifies that the reminder is for a task item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TASK = 'Task';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResolveNamesSearchScopeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResolveNamesSearchScopeType.php
new file mode 100644
index 00000000..b7d0b592
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResolveNamesSearchScopeType.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ResolveNamesSearchScopeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the order and scope for a ResolveNames search.
+ *
+ * @package php-ews\Enumeration
+ */
+class ResolveNamesSearchScopeType extends Enumeration
+{
+ /**
+ * Only the Active Directory directory service is searched.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACTIVE_DIRECTORY = 'ActiveDirectory';
+
+ /**
+ * Active Directory is searched first, and then the contact folders that are
+ * specified in the ParentFolderIds property are searched.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACTIVE_DIRECTORY_CONTACTS = 'ActiveDirectoryContacts';
+
+ /**
+ * Only the contact folders that are identified by the ParentFolderIds
+ * property are searched.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS = 'Contacts';
+
+ /**
+ * Contact folders that are identified by the ParentFolderIds property are
+ * searched first and then Active Directory is searched.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_ACTIVE_DIRECTORY = 'ContactsActiveDirectory';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseClassType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseClassType.php
new file mode 100644
index 00000000..f9de8995
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseClassType.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ResponseClassType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the status of a response.
+ *
+ * @package php-ews\Enumeration
+ */
+class ResponseClassType extends Enumeration
+{
+ /**
+ * Describes a request that cannot be fulfilled.
+ *
+ * The following are examples of sources of errors:
+ * - Invalid attributes or elements
+ * - Attributes or elements that are out of range
+ * - An unknown tag
+ * - An attribute or element that is not valid in the context
+ * - An unauthorized access attempt by any client
+ * - A server-side failure in response to a valid client-side call
+ * - Information about the error can be found in the ResponseCode and
+ * MessageText elements.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ERROR = 'Error';
+
+ /**
+ * Describes a request that is fulfilled.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SUCCESS = 'Success';
+
+ /**
+ * Describes a request that was not processed.
+ *
+ * A warning may be returned if an error occurred while an item in the
+ * request was processing and subsequent items could not be processed. The
+ * following are examples of sources of warnings:
+ * - The Exchange store is offline during the batch.
+ * - Active Directory Domain Services (AD DS) is offline.
+ * - Mailboxes were moved.
+ * - The message database (MDB) is offline.
+ * - A password is expired.
+ * - A quota has been exceeded.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WARNING = 'Warning';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseCodeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseCodeType.php
new file mode 100644
index 00000000..fdd094e5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseCodeType.php
@@ -0,0 +1,4866 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ResponseCodeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Provides status information about a request.
+ *
+ * @package php-ews\Enumeration
+ */
+class ResponseCodeType extends Enumeration
+{
+ /**
+ * This error occurs when the calling account does not have the rights to
+ * perform the requested action.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACCESS_DENIED = 'ErrorAccessDenied';
+
+ /**
+ * This error is for internal use only. This error is not returned.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACCESS_MODE_SPECIFIED = 'ErrorAccessModeSpecified';
+
+ /**
+ * This error occurs when the account in question has been disabled.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACCOUNT_DISABLED = 'ErrorAccountDisabled';
+
+ /**
+ * This error occurs when AD DS is unavailable; Try your request again
+ * later.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const AD_UNAVAILABLE = 'ErrorADUnavailable';
+
+ /**
+ * This error occurs when a list with added delegates cannot be saved.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ADD_DELEGATES_FAILED = 'ErrorAddDelegatesFailed';
+
+ /**
+ * This error occurs when the address space record, or Domain Name System
+ * (DNS) domain name, for cross-forest availability could not be found in
+ * the Active Directory database.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ADDRESS_SPACE_NOT_FOUND = 'ErrorAddressSpaceNotFound';
+
+ /**
+ * This error indicates that the AffectedTaskOccurrences attribute was not
+ * specified.
+ *
+ * When the DeleteItem element is used to delete at least one item that is a
+ * task, and regardless of whether that task is recurring or not, the
+ * AffectedTaskOccurrences attribute has to be specified so that DeleteItem
+ * can determine whether to delete the current occurrence or the entire
+ * series.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const AFFECTED_TASK_OCCURRENCES_REQUIRED = 'ErrorAffectedTaskOccurrencesRequired';
+
+ /**
+ * This error MUST be returned if an action cannot be applied to one or more
+ * items in the conversation.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const APPLY_CONVERSATION_ACTION_FAILED = 'ErrorApplyConversationActionFailed';
+
+ /**
+ * Indicates that the archive mailbox was not enabled.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ARCHIVE_MAILBOX_NOT_ENABLED = 'ErrorArchiveMailboxNotEnabled';
+
+ /**
+ * This error is returned when an archive mailbox search is unsuccessful.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ARCHIVE_MAILBOX_SEARCH_FAILED = 'ErrorArchiveMailboxSearchFailed';
+
+ /**
+ * Indicates that archive mailbox service discovery failed.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ARCHIVE_MAILBOX_SERVICE_DISCOVERY_FAILED = 'ErrorArchiveMailboxServiceDiscoveryFailed';
+
+ /**
+ * Specifies that an attempt was made to create an item with more than 10
+ * nested attachments.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const ATTACHMENT_NEST_LEVEL_LIMIT_EXCEEDED = 'ErrorAttachmentNestLevelLimitExceeded';
+
+ /**
+ * This error occurs if an attempt to create or retrieve an attachment with
+ * size exceeding a 32-bit integer in bytes.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ATTACHMENT_SIZE_LIMIT_EXCEEDED = 'ErrorAttachmentSizeLimitExceeded';
+
+ /**
+ * This error indicates that Exchange Web Services tried to determine the
+ * location of a cross-forest computer that is running Exchange that has the
+ * Client Access server role installed by using the Autodiscover service,
+ * but the call to the Autodiscover service failed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const AUTO_DISCOVERY_FAILED = 'ErrorAutoDiscoverFailed';
+
+ /**
+ * This error indicates that the availability configuration information for
+ * the local forest is missing from AD DS.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const AVAILABILITY_CONFIG_NOT_FOUND = 'ErrorAvailabilityConfigNotFound';
+
+ /**
+ * This error indicates that an exception occurred while processing an item
+ * and that exception is likely to occur for the items that follow.
+ *
+ * Requests may include multiple items; for example, a GetItem operation
+ * request might include multiple identifiers. In general, items are
+ * processed one at a time. If an exception occurs while processing an item
+ * and that exception is likely to occur for the items that follow, items
+ * that follow will not be processed.
+ *
+ * The following are examples of errors that will stop processing for items
+ * that follow:
+ * - ErrorAccessDenied
+ * - ErrorAccountDisabled
+ * - ErrorADUnavailable
+ * - ErrorADOperation
+ * - ErrorConnectionFailed
+ * - ErrorMailboxStoreUnavailable
+ * - ErrorMailboxMoveInProgress
+ * - ErrorPasswordChangeRequired
+ * - ErrorPasswordExpired
+ * - ErrorQuotaExceeded
+ * - ErrorInsufficientResources
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const BATCH_PROCESSING_STOPPED = 'ErrorBatchProcessingStopped';
+
+ /**
+ * This error is reported on Create/Update calendar item or task recurrence
+ * properties when the property value is out of range.
+ *
+ * For example, specifying the fifteenth week of the month will result in
+ * this response code.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_OUT_OF_RANGE = 'ErrorCalendarOutOfRange';
+
+ /**
+ * Indicates that an attempt was made to archive a calendar contact task folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CANNOT_ARCHIVE_CALENDAR_CONTACT_TASK_FOLDER = 'ErrorCannotArchiveCalendarContactTaskFolderException';
+
+ /**
+ * Indicates that attempt was made to archive items in the archive mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CANNOT_ARCHIVE_ITEM_IN_ARCHIVE_MAILBOX = 'ErrorCannotArchiveItemsInArchiveMailbox';
+
+ /**
+ * Indicates that an attempt was made to archive items in public folders.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CANNOT_ARCHIVE_ITEMS_IN_PUBLIC_FOLDERS = 'ErrorCannotArchiveItemsInPublicFolders';
+
+ /**
+ * This error occurs when a calendar item is being created and the
+ * SavedItemFolderId attribute refers to a non-calendar folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_CREATE_CALENDAR_ITEM_FOLDER = 'ErrorCannotCreateCalendarItemInNonCalendarFolder';
+
+ /**
+ * This error occurs when a contact is being created and the
+ * SavedItemFolderId attribute refers to a non-contact folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_CREATE_CONTACT_IN_FOLDER = 'ErrorCannotCreateContactInNonContactFolder';
+
+ /**
+ * This error indicates that a post item cannot be created in a folder other
+ * than a mail folder, such as Calendar, Contact, Tasks, Notes, and so on.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_CREATE_POST_IN_FOLDER = 'ErrorCannotCreatePostItemInNonMailFolder';
+
+ /**
+ * This error occurs when a task is being created and the SavedItemFolderId
+ * attribute refers to a non-task folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_CREATE_TASK_IN_FOLDER = 'ErrorCannotCreateTaskInNonTaskFolder';
+
+ /**
+ * This error occurs when the item or folder to delete cannot be deleted.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_DELETE_OBJECT = 'ErrorCannotDeleteObject';
+
+ /**
+ * The DeleteItem Operation returns this error when it fails to delete the
+ * current occurrence of a recurring task.
+ *
+ * This can only happen if the AffectedTaskOccurrences attribute has been
+ * set to SpecifiedOccurrenceOnly.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_DELETE_TASK_OCCURRENCE = 'ErrorCannotDeleteTaskOccurrence';
+
+ /**
+ * Indicates that an attempt was made to disable a mandatory extension.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CANNOT_DISABLE_MANDATORY_EXTENSION = 'ErrorCannotDisableMandatoryExtension';
+
+ /**
+ * This error must be returned when the server cannot empty a folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CANNOT_EMPTY_FOLDER = 'ErrorCannotEmptyFolder';
+
+ /**
+ * Specifies that the server could not retrieve the external URL for Outlook
+ * Web App Options.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CANNOT_GET_EXTERNAL_ECP_URL = 'ErrorCannotGetExternalEcpUrl';
+
+ /**
+ * Indicates that the source folder path could not be retrieved.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CANNOT_GET_SOURCE_FOLDER_PATH = 'ErrorCannotGetSourceFolderPath';
+
+ /**
+ * This error occurs when an attempt is made to move or copy an occurrence
+ * of a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_MOVE_OR_COPY_OCCURRENCE = 'ErrorCalendarCannotMoveOrCopyOccurrence';
+
+ /**
+ * The GetAttachment operation returns this error if it cannot retrieve the
+ * body of a file attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_OPEN_FILE_ATTACHMENT = 'ErrorCannotOpenFileAttachment';
+
+ /**
+ * This error indicates that the caller tried to set calendar permissions on
+ * a non-calendar folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_SET_CALENDAR_PERMISSION_ON_FOLDER = 'ErrorCannotSetCalendarPermissionOnNonCalendarFolder';
+
+ /**
+ * This error indicates that the caller tried to set non-calendar permissions on a calendar folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_SET_NON_CALENDAR_PERMISSION_ON_FOLDER = 'ErrorCannotSetNonCalendarPermissionOnCalendarFolder';
+
+ /**
+ * This error indicates that you cannot set unknown permissions in a
+ * permissions set.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_SET_PERMISSION_UNKNOWN_ENTRIES = 'ErrorCannotSetPermissionUnknownEntries';
+
+ /**
+ * Indicates that an attempt was made to specify the search folder as the
+ * source folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CANNOT_SPECIFY_SEARCH_FOLDER_AS_SOURCE = 'ErrorCannotSpecifySearchFolderAsSourceFolder';
+
+ /**
+ * This error occurs when an attempt is made to update a calendar item that
+ * is located in the Deleted Items folder and when meeting updates or
+ * cancellations are to be sent according to the value of the
+ * SendMeetingInvitationsOrCancellations attribute.
+ *
+ * The following are the possible values for this attribute:
+ * - SendToAllAndSaveCopy
+ * - SendToChangedAndSaveCopy
+ * - SendOnlyToAll
+ * - SendOnlyToChanged
+ *
+ * However, such an update is allowed only when the value of this attribute
+ * is set to SendToNone.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_UPDATE_DELETED_ITEM = 'ErrorCalendarCannotUpdateDeletedItem';
+
+ /**
+ * This error occurs when a request that requires an item identifier is
+ * given a folder identifier.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_USE_FOLDER_ID_FOR_ITEM_ID = 'ErrorCannotUseFolderIdForItemId';
+
+ /**
+ * This error occurs when the UpdateItem, GetItem, DeleteItem, MoveItem,
+ * CopyItem, or SendItem operation is called and the ID that was specified
+ * is not an occurrence ID of any recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_USE_ID_FOR_OCCURRENCE_ID = 'ErrorCalendarCannotUseIdForOccurrenceId';
+
+ /**
+ * This error occurs when the UpdateItem, GetItem, DeleteItem, MoveItem,
+ * CopyItem, or SendItem operation is called and the ID that was specified
+ * is not an ID of any recurring master item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_USE_ID_FOR_RECURRING_MASTER_ID = 'ErrorCalendarCannotUseIdForRecurringMasterId';
+
+ /**
+ * This error occurs when a request that requires a folder identifier is
+ * given an item identifier.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CANNOT_USE_ITEM_ID_FOR_FOLDER_ID = 'ErrorCannotUseItemIdForFolderId';
+
+ /**
+ * This response code has been replaced by
+ * ErrorChangeKeyRequiredForWriteOperations.
+ *
+ * @since Exchange 2007
+ * @deprecated Exchange 2007
+ *
+ * @var string
+ */
+ const CHANGE_KEY_REQUIRED = 'ErrorChangeKeyRequired';
+
+ /**
+ * This error is returned when the change key for an item is missing or
+ * stale.
+ *
+ * For SendItem, UpdateItem, and UpdateFolder operations, the caller must
+ * pass in a correct and current change key for the item. Note that this is
+ * the case with UpdateItem even when conflict resolution is set to always
+ * overwrite.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CHANGE_KEY_REQUIRED_FOR_WRITE = 'ErrorChangeKeyRequiredForWriteOperations';
+
+ /**
+ * Specifies that the client was disconnected.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CLIENT_DISCONNECTED = 'ErrorClientDisconnected';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CLIENT_INTENT_INVALID_STATE_DEFINITION = 'ErrorClientIntentInvalidStateDefinition';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CLIENT_INTENT_NOT_FOUND = 'ErrorClientIntentNotFound';
+
+ /**
+ * This error occurs when Exchange Web Services cannot connect to the
+ * mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONNECTION_FAILED = 'ErrorConnectionFailed';
+
+ /**
+ * This error indicates that the property that was inspected for a Contains
+ * filter is not a string type.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONTAINS_FILTER_WRONG_TYPE = 'ErrorContainsFilterWrongType';
+
+ /**
+ * The GetItem operation returns this error when Exchange Web Services is
+ * unable to retrieve the MIME content for the item requested; the
+ * CreateItem operation returns this error when Exchange Web Services is
+ * unable to create the item from the supplied MIME content.
+ *
+ * Usually this is an indication that the item property is corrupted or
+ * truncated.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTENT_CONVERSION_FAILED = 'ErrorContentConversionFailed';
+
+ /**
+ * This error occurs when a search request is made using the QueryString
+ * option and content indexing is not enabled for the target mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONTENT_INDEXING_NOT_ENABLED = 'ErrorContentIndexingNotEnabled';
+
+ /**
+ * This error occurs when the data is corrupted and cannot be processed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CORRUPT_DATA = 'ErrorCorruptData';
+
+ /**
+ * This error occurs when the caller does not have permission to create the
+ * item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CREATE_ITEM_ACCESS_DENIED = 'ErrorCreateItemAccessDenied';
+
+ /**
+ * This error occurs when one or more of the managed folders that were
+ * specified in the CreateManagedFolder operation request failed to be
+ * created.
+ *
+ * Search for each folder to determine which folders were created and which
+ * folders do not exist.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CREATE_MANAGED_FOLDER_PARTIAL_COMPLETION = 'ErrorCreateManagedFolderPartialCompletion';
+
+ /**
+ * This error occurs when the calling account does not have the permissions
+ * required to create the subfolder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CREATE_SUBFOLDER_ACCESS_DENIED = 'ErrorCreateSubfolderAccessDenied';
+
+ /**
+ * This error occurs when an attempt is made to move an item or folder
+ * from one mailbox to another; if the source mailbox and destination
+ * mailbox are different, you will get this error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CROSS_MAILBOX_MOVE_COPY = 'ErrorCrossMailboxMoveCopy';
+
+ /**
+ * This error indicates that the request is not allowed because the Client
+ * Access server that should service the request is in a different site.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CROSS_SITE_REQUEST = 'ErrorCrossSiteRequest';
+
+ /**
+ * This error can occur in the following scenarios:
+ * - An attempt is made to access or write a property on an item and the
+ * property value is too large.
+ * - The base64 encoded MIME content length within the request XML exceeds
+ * the limit.
+ * - The size of the body of an existing item body exceeds the limit.
+ * - The consumer tries to set an HTML or text body whose length (or
+ * combined length in the case of append) exceeds the limit.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DATA_SIZE_LIMIT_EXCEEDED = 'ErrorDataSizeLimitExceeded';
+
+ /**
+ * This error occurs when the underlying data provider fails to complete the
+ * operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DATA_SOURCE_OPERATION = 'ErrorDataSourceOperation';
+
+ /**
+ * This error occurs in an AddDelegate operation when the specified user
+ * already exists in the list of delegates.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATE_ALREADY_EXISTS = 'ErrorDelegateAlreadyExists';
+
+ /**
+ * This error occurs in an AddDelegate operation when the specified user to
+ * be added is the owner of the mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATE_CANNOT_ADD_OWNER = 'ErrorDelegateCannotAddOwner';
+
+ /**
+ * This error occurs in a GetDelegate operation when either there is no
+ * delegate information on the local FreeBusy message or no Active Directory
+ * public delegate (no “public delegate” or no "Send On Behalf" entry in AD
+ * DS).
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATE_MISSING_CONFIGURATION = 'ErrorDelegateMissingConfiguration';
+
+ /**
+ * This error occurs when a specified user cannot be mapped to a user in AD
+ * DS.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATE_NO_USER = 'ErrorDelegateNoUser';
+
+ /**
+ * This error occurs in the AddDelegate operation when an added delegate
+ * user is not valid.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const DELEGATE_VALIDATION_FAILED = 'ErrorDelegateValidationFailed';
+
+ /**
+ * This error occurs when an attempt is made to delete a distinguished
+ * folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DELETE_DISTINGUISHED_FOLDER = 'ErrorDeleteDistinguishedFolder';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DELETE_ITEMS_FAILED = 'ErrorDeleteItemsFailed';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DELETE_UNIFIED_MESSAGING_PROMPT_FAILED = 'ErrorDeleteUnifiedMessagingPromptFailed';
+
+ /**
+ * This error is returned when discovery searches are disabled on a tenant
+ * or server.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DISCOVERY_SEARCHES_DISABLED = 'ErrorDiscoverySearchesDisabled';
+
+ /**
+ * This error indicates that a distinguished user ID is not valid for the
+ * operation; DistinguishedUserType should not be present in the request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DISTINGUISHED_USER_NOT_SUPPORTED = 'ErrorDistinguishedUserNotSupported';
+
+ /**
+ * This error indicates that a request distribution list member does not
+ * exist in the distribution list.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DISTRIBUTION_LIST_MEMBER_NOT_EXIST = 'ErrorDistributionListMemberNotExist';
+
+ /**
+ * This error occurs when duplicate folder names are specified within the
+ * FolderNames element of the CreateManagedFolder operation request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DUPLICATE_INPUT_FOLDER_NAMES = 'ErrorDuplicateInputFolderNames';
+
+ /**
+ * This error is returned when there are duplicate legacy distinguished
+ * names in Active Directory Domain Services (AD DS).
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DUPLICATE_LEGACY_DISTINGUISHED_NAME = 'ErrorDuplicateLegacyDistinguishedName';
+
+ /**
+ * This error indicates that there are duplicate SOAP headers.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DUPLICATE_SOAP_HEADER = 'ErrorDuplicateSOAPHeader';
+
+ /**
+ * This error indicates that a duplicate user ID has been found in a
+ * permission set, either Default or Anonymous are set more than once, or
+ * there are duplicate SIDs or recipients.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DUPLICATE_USER_IDS = 'ErrorDuplicateUserIdsSpecified';
+
+ /**
+ * This error occurs during a CreateItem or UpdateItem operation when a
+ * calendar item duration is longer than the maximum allowed, which is
+ * currently 5 years.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DURATION_IS_TOO_LONG = 'ErrorCalendarDurationIsTooLong';
+
+ /**
+ * This error occurs when a request attempts to create/update the search
+ * parameters of a search folder.
+ *
+ * For example, this can occur when a search folder is created in the
+ * mailbox but the search folder is directed to look in another mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EMAIL_ADDRESS_MISMATCH = 'ErrorEmailAddressMismatch';
+
+ /**
+ * This error occurs when a calendar End time is set to the same time or
+ * after the Start time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const END_DATE_IS_EARLIER_THAN_START_DATE = 'ErrorCalendarEndDateIsEarlierThanStartDate';
+
+ /**
+ * This error occurs when the operation failed because of communication
+ * problems with Active Directory Domain Services (AD DS).
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ERROR_AD_OPERATION = 'ErrorADOperation';
+
+ /**
+ * This error occurs when a ResolveNames operation request specifies a name
+ * that is not valid.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ERROR_AD_SESSION_FILTER = 'ErrorADSessionFilter';
+
+ /**
+ * Indicates an error in archive folder path creation.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ERROR_ARCHIVE_FOLDER_PATH_CREATION = 'ErrorArchiveFolderPathCreation';
+
+ /**
+ * This error occurs when the event that is associated with a watermark is
+ * deleted before the event is returned.
+ *
+ * When this error is returned, the subscription is also deleted.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EVENT_NOT_FOUND = 'ErrorEventNotFound';
+
+ /**
+ * This error indicates that there are more concurrent requests against the
+ * server than are allowed by a user's policy.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEEDED_CONNECTION_COUNT = 'ErrorExceededConnectionCount';
+
+ /**
+ * This error indicates that a search operation call has exceeded the total
+ * number of items that can be returned.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEEDED_FIND_COUNT = 'ErrorExceededFindCountLimit';
+
+ /**
+ * This error indicates that a user's throttling policy maximum subscription
+ * count has been exceeded.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEEDED_SUBSCRIPTION_COUNT = 'ErrorExceededSubscriptionCount';
+
+ /**
+ * This error occurs if the GetEvents Operation is called as a subscription
+ * is being deleted because it has expired.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EXPIRED_SUBSCRIPTION = 'ErrorExpiredSubscription';
+
+ /**
+ * Indicates that the extension was not found.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXTENSION_NOT_FOUND = 'ErrorExtensionNotFound';
+
+ /**
+ * This error occurs when the folder is corrupted and cannot be saved.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_CORRUPT = 'ErrorFolderCorrupt';
+
+ /**
+ * This error occurs when an attempt is made to create a folder that has the
+ * same name as another folder in the same parent.
+ *
+ * Duplicate folder names are not allowed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_EXISTS = 'ErrorFolderExists';
+
+ /**
+ * This error occurs when the specified folder for a FindItem operation with
+ * a CalendarView element is not of calendar folder type.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_INVALID_FOR_CALENDAR_VIEW = 'ErrorCalendarFolderIsInvalidForCalendarView';
+
+ /**
+ * This error indicates that the folder ID that was specified does not
+ * correspond to a valid folder, or that the delegate does not have
+ * permission to access the folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_NOT_FOUND = 'ErrorFolderNotFound';
+
+ /**
+ * This error indicates that the requested property could not be retrieved.
+ *
+ * This does not indicate that the property does not exist, but that the
+ * property was corrupted in some way so that the retrieval failed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_PROPERTY_REQUEST_FAILED = 'ErrorFolderPropertRequestFailed';
+
+ /**
+ * This error indicates that the folder could not be created or updated
+ * because of an invalid state.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_SAVE_ERROR = 'ErrorFolderSave';
+
+ /**
+ * This error indicates that the folder could not be created or updated
+ * because of an invalid state.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_SAVE_FAILED = 'ErrorFolderSaveFailed';
+
+ /**
+ * This error indicates that the folder could not be created or updated
+ * because of invalid property values.
+ *
+ * The response code lists which properties caused the problem.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_SAVE_PROPERTY_ERROR = 'ErrorFolderSavePropertyError';
+
+ /**
+ * This error indicates that the maximum group member count has been reached
+ * for obtaining free/busy information for a distribution list.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FREE_BUSY_DL_LIMIT_REACHED = 'ErrorFreeBusyDLLimitReached';
+
+ /**
+ * This error is returned when free/busy information cannot be retrieved
+ * because of an intervening failure.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FREE_BUSY_GENERATION_FAILED = 'ErrorFreeBusyGenerationFailed';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const GET_SERVER_SECURITY_DESCRIPTOR_FAILED = 'ErrorGetServerSecurityDescriptorFailed';
+
+ /**
+ * This error is returned when new instant messaging (IM) contacts cannot be
+ * added because the maximum number of contacts has been reached.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const IM_CONTACT_LIMIT_REACHED = 'ErrorImContactLimitReached';
+
+ /**
+ * This error is returned when an attempt is made to add a group display
+ * name when an existing group already has the same display name.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const IM_GROUP_DISPLAY_NAME_EXISTS = 'ErrorImGroupDisplayNameAlreadyExists';
+
+ /**
+ * This error is returned when new IM groups cannot be added because the
+ * maximum number of groups has been reached.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const IM_GROUP_LIMIT_REACHED = 'ErrorImGroupLimitReached';
+
+ /**
+ * The error is returned in the server-to-server authorization case for
+ * Exchange Impersonation when the caller does not have the proper rights to
+ * impersonate the specific user in question.
+ *
+ * This error maps to the ms-Exch-EPI-May-Impersonate extended Active
+ * Directory right.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IMPERSONATE_USER_DENIED = 'ErrorImpersonateUserDenied';
+
+ /**
+ * This error is returned in the server-to-server authorization for Exchange
+ * Impersonation when the caller does not have the proper rights to
+ * impersonate through the Client Access server that they are making the
+ * request against.
+ *
+ * This maps to the ms-Exch-EPI-Impersonation extended Active Directory
+ * right.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IMPERSONATION_DENIED = 'ErrorImpersonationDenied';
+
+ /**
+ * This error indicates that there was an unexpected error when an attempt
+ * was made to perform server-to-server authentication.
+ *
+ * This response code typically indicates either that the service account
+ * that is running the Exchange Web Services application pool is configured
+ * incorrectly, that Exchange Web Services cannot talk to the directory, or
+ * that a trust between forests is not correctly configured.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IMPERSONATION_FAILED = 'ErrorImpersonationFailed';
+
+ /**
+ * This error MUST be returned if any rule does not validate.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INBOX_RULES_VALIDATION_ERROR = 'ErrorInboxRulesValidationError';
+
+ /**
+ * This error indicates that the request was valid for the current Exchange
+ * Server version but was invalid for the request server version that was
+ * specified.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INCORRECT_SCHEMA_VERSION = 'ErrorIncorrectSchemaVersion';
+
+ /**
+ * This error indicates that each change description in the UpdateItem or
+ * UpdateFolder elements must list only one property to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INCORRECT_UPDATE_PROPERTY_COUNT = 'ErrorIncorrectUpdatePropertyCount';
+
+ /**
+ * This error occurs when the request contains too many attendees to
+ * resolve. By default, the maximum number of attendees to resolve is 100.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INDIVIDUAL_MAILBOX_LIMIT_REACHED = 'ErrorIndividualMailboxLimitReached';
+
+ /**
+ * This error occurs when the mailbox server is overloaded. Try your request
+ * again later.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INSUFFICIENT_RESOURCES = 'ErrorInsufficientResources';
+
+ /**
+ * This error indicates that Exchange Web Services encountered an error that
+ * it could not recover from, and a more specific response code that is
+ * associated with the error that occurred does not exist.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INTERNAL_SERVER_ERROR = 'ErrorInternalServerError';
+
+ /**
+ * This error indicates that an internal server error occurred and that you
+ * should try your request again later.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INTERNAL_SERVER_TRANSIENT_ERROR = 'ErrorInternalServerTransientError';
+
+ /**
+ * This error indicates that the level of access that the caller has on the
+ * free/busy data is invalid.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ACCESS_LEVEL = 'ErrorInvalidAccessLevel';
+
+ /**
+ * This error indicates that the requesting account is not a valid account
+ * in the directory database.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_AD_ACCOUNT = 'ErrorCallerIsInvalidADAccount';
+
+ /**
+ * This error indicates an error caused by all invalid arguments passed to
+ * the GetMessageTrackingReport Operation.
+ *
+ * This error is returned in the following scenarios:
+ * - The user specified in the sending-as parameter does not exist in the
+ * directory.
+ * - The user specified in the sending-as parameter is not unique in the
+ * directory.
+ * - The sending-as address is empty.
+ * - The sending-as address is not a valid e-mail address.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_ARGUMENT = 'ErrorInvalidArgument';
+
+ /**
+ * This error is returned by the GetAttachment Operation or the
+ * DeleteAttachment Operation when an attachment that corresponds to the
+ * specified ID is not found.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ATTACHMENT_ID = 'ErrorInvalidAttachmentId';
+
+ /**
+ * This error occurs when you try to bind to an existing search folder by
+ * using a complex attachment table restriction.
+ *
+ * Exchange Web Services only supports simple contains filters against the
+ * attachment table. If you try to bind to an existing search folder that
+ * has a more complex attachment table restriction (a subfilter), Exchange
+ * Web Services cannot render the XML for that filter and returns this
+ * response code.
+ *
+ * Note that you can still call the GetFolder operation on the folder, but
+ * do not request the SearchParameters property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ATTACHMENT_SUBFILTER = 'ErrorInvalidAttachmentSubfilter';
+
+ /**
+ * This error occurs when you try to bind to an existing search folder by
+ * using a complex attachment table restriction.
+ *
+ * Exchange Web Services only supports simple contains filters against the
+ * attachment table. If you try to bind to an existing search folder that
+ * has a more complex attachment table restriction, Exchange Web Services
+ * cannot render the XML for that filter. In this case, the attachment
+ * subfilter contains a text filter, but it is not looking at the attachment
+ * display name.
+ *
+ * Note that you can still call the GetFolder operation on the folder, but
+ * do not request the SearchParameters property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ATTACHMENT_SUBFILTER_TEXT = 'ErrorInvalidAttachmentSubfilterTextFilter';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ATTRIBUTE_VALUE = 'ErrorCalendarInvalidAttributeValue';
+
+ /**
+ * This error indicates that the authorization procedure for the requester
+ * failed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_AUTHORIZATION_CONTEXT = 'ErrorInvalidAuthorizationContext';
+
+ /**
+ * This error occurs when a consumer passes in a folder or item identifier
+ * with a change key that cannot be parsed.
+ *
+ * For example, this could be invalid base64 content or an empty string.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_CHANGE_KEY = 'ErrorInvalidChangeKey';
+
+ /**
+ * This error indicates that a request to get a client access token was not
+ * valid.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_CLIENT_ACCESS_TOKEN_REQUEST = 'ErrorInvalidClientAccessTokenRequest';
+
+ /**
+ * This error indicates that there was an internal error when an attempt was
+ * made to resolve the identity of the caller.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_CLIENT_SECURITY_CONTEXT = 'ErrorInvalidClientSecurityContext';
+
+ /**
+ * This error is returned when an attempt is made to set the CompleteDate
+ * element value of a task to a time in the future.
+ *
+ * When it is converted to the local time of the Client Access server, the
+ * CompleteDate of a task cannot be set to a value that is later than the
+ * local time on the Client Access server.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_COMPLETE_DATE = 'ErrorInvalidCompleteDate';
+
+ /**
+ * This error indicates that an invalid e-mail address was provided for a
+ * contact.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_CONTACT_EMAIL_ADDRESS = 'ErrorInvalidContactEmailAddress';
+
+ /**
+ * This error indicates that an invalid e-mail index value was provided for
+ * an e-mail entry.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_CONTACT_EMAIL_INDEX = 'ErrorInvalidContactEmailIndex';
+
+ /**
+ * This error occurs when the credentials that are used to proxy a request
+ * to a different directory service forest fail authentication.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_CROSS_FOREST_CREDENTIALS = 'ErrorInvalidCrossForestCredentials';
+
+ /**
+ * This error occurs during a CreateItem or UpdateItem operation when
+ * invalid values of Day, WeekendDay, and Weekday are used to define the
+ * time change pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_DAY_FOR_TIME_CHANGE_PATTERN = 'ErrorCalendarInvalidDayForTimeChangePattern';
+
+ /**
+ * This error occurs during a CreateItem or UpdateItem operation when
+ * invalid values of Day, WeekDay, and WeekendDay are used to specify the
+ * weekly recurrence.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_DAY_FOR_WEEKLY_RECURRENCE = 'ErrorCalendarInvalidDayForWeeklyRecurrence';
+
+ /**
+ * This error indicates that the specified folder permissions are invalid.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const INVALID_DELEGATE_PERMISSION = 'ErrorInvalidDelegatePermission';
+
+ /**
+ * This error indicates that the specified delegate user ID is invalid.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const INVALID_DELEGATE_USER_ID = 'ErrorInvalidDelegateUserId';
+
+ /**
+ * This error occurs when the bitmask that was passed into an Excludes
+ * element restriction is unable to be parsed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_EXCLUDES_RESTRICTION = 'ErrorInvalidExcludesRestriction';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_EXPRESSION_TYPE_FOR_SUBFILTER = 'ErrorInvalidExpressionTypeForSubFilter';
+
+ /**
+ * This error occurs when the following events take place:
+ * - The caller tries to use an extended property that is not supported by
+ * Exchange Web Services.
+ * - The caller passes in an invalid combination of attribute values for an
+ * extended property. This also occurs if no attributes are passed. Only certain combinations are allowed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_EXTENDED_PROPERTY = 'ErrorInvalidExtendedProperty';
+
+ /**
+ * This error occurs when the value section of an extended property does not
+ * match the type of the property.
+ *
+ * For example, setting an extended property that has PropertyType="String"
+ * to an array of integers will result in this error. Any string
+ * representation that is not coercible into the type that is specified for
+ * the extended property will give this error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_EXTENDED_PROPERTY_VALUE = 'ErrorInvalidExtendedPropertyValue';
+
+ /**
+ * This error indicates that the sharing invitation sender did not create
+ * the sharing invitation metadata.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_EXTERNAL_SHARING_INITIATOR = 'ErrorInvalidExternalSharingInitiator';
+
+ /**
+ * This error indicates that a sharing message is not intended for the
+ * caller.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_EXTERNAL_SHARING_SUBSCRIBER = 'ErrorInvalidExternalSharingSubscriber';
+
+ /**
+ * This error indicates that the requester's organization federation objects
+ * are not correctly configured.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_FEDERATED_ORGANIZATION_ID = 'ErrorInvalidFederatedOrganizationId';
+
+ /**
+ * This error occurs when the folder ID is corrupt.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_FOLDER_ID = 'ErrorInvalidFolderId';
+
+ /**
+ * This error indicates that the specified folder type is invalid for the
+ * current operation.
+ *
+ * For example, you cannot create a Search folder in a public folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_FOLDER_TYPE_FOR_OPERATION = 'ErrorInvalidFolderTypeForOperation';
+
+ /**
+ * This error occurs in fractional paging when the user has specified one of
+ * the following:
+ * - A numerator that is greater than the denominator.
+ * - A numerator that is less than zero.
+ * - A denominator that is less than or equal to zero.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_FRACTIONAL_PAGING_PARAMS = 'ErrorInvalidFractionalPagingParameters';
+
+ /**
+ * This error occurs when the GetUserAvailability Operation is called with a
+ * FreeBusyViewType of None.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_FREE_BUSY_VIEW_TYPE = 'ErrorInvalidFreeBusyViewType';
+
+ /**
+ * This error indicates that the DataType and ShareFolderId elements are
+ * both present in a request.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_GET_SHARING_FOLDER_REQUEST = 'ErrorInvalidGetSharingFolderRequest';
+
+ /**
+ * This error indicates that the ID and/or change key is malformed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ID = 'ErrorInvalidId';
+
+ /**
+ * This error is returned when the specified IM contact identifier does not
+ * represent a valid identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_ID_CONTACT_ID = 'ErrorInvalidImContactId';
+
+ /**
+ * This error occurs when the caller specifies an Id attribute that is
+ * empty.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ID_EMPTY = 'ErrorInvalidIdEmpty';
+
+ /**
+ * This error indicates that a folder or item ID that is using the Exchange
+ * 2007 format was specified for a request with a version of Exchange 2007
+ * SP1 or later.
+ *
+ * You cannot use Exchange 2007 IDs in Exchange 2007 SP1 or later requests.
+ * You have to use the ConvertId Operation to convert them first.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const INVALID_ID_MALFORMED_LEGACY_FORMAT = 'ErrorInvalidIdMalformedEwsLegacyIdFormat';
+
+ /**
+ * This error occurs when the caller specifies an Id attribute that is too
+ * long.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ID_MONIKER_TOO_LONG = 'ErrorInvalidIdMonikerTooLong';
+
+ /**
+ * This error occurs when a contact in your mailbox is corrupt.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ID_RETURNED_BY_RESOLVE_NAMES = 'ErrorInvalidIdReturnedByResolveNames';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ID_XML = 'ErrorInvalidIdXml';
+
+ /**
+ * This error is returned when the specified IM distribution group SMTP
+ * address identifier does not represent a valid identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_IM_DISTRIBUTION_GROUP_SMTP_ADDRESS = 'ErrorInvalidImDistributionGroupSmtpAddress';
+
+ /**
+ * This error is returned when the specified IM group identifier does not
+ * represent a valid identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_IM_GROUP_ID = 'ErrorInvalidImGroupId';
+
+ /**
+ * This error occurs during Exchange Impersonation when a caller does not
+ * specify a UPN, an e-mail address, or a user SID.
+ *
+ * This will also occur if the caller specifies one or more of those and the
+ * values are empty.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_IMPERSONATION_HEADER_DATA = 'ErrorInvalidExchangeImpersonationHeaderData';
+
+ /**
+ * This error occurs if the offset for indexed paging is negative.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_INDEXED_PAGING_PARAMS = 'ErrorInvalidIndexedPagingParameters';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_INTERNET_HEADER_CHILD_NODES = 'ErrorInvalidInternetHeaderChildNodes';
+
+ /**
+ * This error occurs when an attempt is made to use an AcceptItem operation
+ * for an item type other than a meeting request or a calendar item, or when
+ * an attempt is made to accept a calendar item occurrence that is in the
+ * Deleted Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_ACCEPT_ITEM = 'ErrorInvalidItemForOperationAcceptItem';
+
+ /**
+ * Indicates that the item was invalid for an ArchiveItem operation.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_ARCHIVE_ITEM = 'ErrorInvalidItemForOperationArchiveItem';
+
+ /**
+ * This error occurs when an attempt is made to use a CancelItem operation
+ * on an item type other than a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_CANCEL_ITEM = 'ErrorInvalidItemForOperationCancelItem';
+
+ /**
+ * This error is returned when an attempt is made to create an item
+ * attachment of an unsupported type.
+ *
+ * Supported item types for item attachments include the following objects:
+ * - ItemType
+ * - MessageType
+ * - CalendarItemType
+ * - TaskType
+ * - ContactItemType
+ *
+ * For example, if you try to create a MeetingMessage attachment, you will
+ * encounter this response code.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_CREATE_ATTACHMENT = 'ErrorInvalidItemForOperationCreateItemAttachment';
+
+ /**
+ * This error is returned from a CreateItem Operation if the request
+ * contains an unsupported item type.
+ *
+ * Supported items include the following objects:
+ * - ItemType
+ * - MessageType
+ * - CalendarItemType
+ * - TaskType
+ * - ContactItemType
+ *
+ * Certain types are created as a side effect of doing something else.
+ * MeetingMessages, for example, are created when you send a calendar item
+ * to attendees; they are not explicitly created.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_CREATE_ITEM = 'ErrorInvalidItemForOperationCreateItem';
+
+ /**
+ * This error occurs when an attempt is made to use a DeclineItem operation
+ * for an item type other than a meeting request or a calendar item, or when
+ * an attempt is made to decline a calendar item occurrence that is in the
+ * Deleted Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_DECLINE_ITEM = 'ErrorInvalidItemForOperationDeclineItem';
+
+ /**
+ * This error indicates that the ExpandDL Operation is valid only for
+ * private distribution lists.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_EXPAND_DISTRIBUTION_LIST = 'ErrorInvalidItemForOperationExpandDL';
+
+ /**
+ * This error is returned from a RemoveItem operation if the request
+ * specifies an item that is not a meeting cancellation item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_REMOVE_ITEM = 'ErrorInvalidItemForOperationRemoveItem';
+
+ /**
+ * This error is returned from a SendItem Operation if the request specifies
+ * an item that is not a message item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_SEND_ITEM = 'ErrorInvalidItemForOperationSendItem';
+
+ /**
+ * This error occurs when an attempt is made to use TentativelyAcceptItem
+ * for an item type other than a meeting request or a calendar item, or when
+ * an attempt is made to tentatively accept a calendar item occurrence that
+ * is in the Deleted Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ITEM_FOR_TENTATIVE = 'ErrorInvalidItemForOperationTentative';
+
+ /**
+ * This error is for internal use only.
+ *
+ * This error is not returned.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_LOGON_TYPE = 'ErrorInvalidLogonType';
+
+ /**
+ * This error indicates that the CreateItem Operation or the UpdateItem
+ * Operation failed while creating or updating a personal distribution list.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_MAILBOX = 'ErrorInvalidMailbox';
+
+ /**
+ * This error occurs when the structure of the managed folder is corrupted
+ * and cannot be rendered.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_MANAGED_FOLDER_PROPERTY = 'ErrorInvalidManagedFolderProperty';
+
+ /**
+ * This error occurs when the quota that is set on the managed folder is
+ * less than zero, which indicates a corrupted managed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_MANAGED_FOLDER_QUOTE = 'ErrorInvalidManagedFolderQuota';
+
+ /**
+ * This error occurs when the size that is set on the managed folder is less
+ * than zero, which indicates a corrupted managed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_MANAGED_FOLDER_SIZE = 'ErrorInvalidManagedFolderSize';
+
+ /**
+ * This error is returned if the ManagementRole header in the SOAP header is
+ * incorrect.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_MANAGEMENT_ROLE_HEADER = 'ErrorInvalidManagementRoleHeader';
+
+ /**
+ * This error occurs when the supplied merged free/busy internal value is
+ * invalid.
+ *
+ * The default minimum value is 5 minutes. The default maximum value is
+ * 1440 minutes.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_MERGED_FREE_BUSY_INTERVAL = 'ErrorInvalidMergedFreeBusyInterval';
+
+ /**
+ * This error occurs when the name is invalid for the ResolveNames
+ * Operation.
+ *
+ * For example, a zero length string, a single space, a comma, and a dash
+ * are all invalid names.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_NAME_FOR_NAME_RESOLUTION = 'ErrorInvalidNameForNameResolution';
+
+ /**
+ * This error indicates an error in the Network Service account on the
+ * Client Access server.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_NETWORK_SERVICE_CONTEXT = 'ErrorInvalidNetworkServiceContext';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_OOF_PARAMETER = 'ErrorInvalidOofParameter';
+
+ /**
+ * This is a general error that is used when the requested operation is
+ * invalid.
+ *
+ * For example, you cannot do the following:
+ * - Perform a “Deep” traversal by using the FindFolder Operation on a
+ * public folder.
+ * - Move or copy the public folder root.
+ * - Delete an associated item by using any mode except “Hard” delete.
+ * - Move or copy an associated item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_OPERATION = 'ErrorInvalidOperation';
+
+ /**
+ * This error indicates that a caller requested free/busy information for a
+ * user in another organization but the organizational relationship does not
+ * have free/busy enabled.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_ORG_RELATION_FOR_FREE_BUSY = 'ErrorInvalidOrganizationRelationshipForFreeBusy';
+
+ /**
+ * This error occurs when a consumer passes in a zero or a negative value
+ * for the maximum rows to be returned.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PAGING_MAX_ROWS = 'ErrorInvalidPagingMaxRows';
+
+ /**
+ * This error occurs when a consumer passes in an invalid parent folder for
+ * an operation.
+ *
+ * For example, this error is returned if you try to create a folder within
+ * a search folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PARENT_FOLDER = 'ErrorInvalidParentFolder';
+
+ /**
+ * This error is returned when an attempt is made to set a task completion
+ * percentage to an invalid value.
+ *
+ * The value must be between 0 and 100 (inclusive).
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PERCENT_COMPLETE = 'ErrorInvalidPercentCompleteValue';
+
+ /**
+ * This error indicates that the permission level is inconsistent with the
+ * permission settings.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PERMISSION_SETTINGS = 'ErrorInvalidPermissionSettings';
+
+ /**
+ * This error indicates that the caller identifier is not valid.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_PHONE_CALL_ID = 'ErrorInvalidPhoneCallId';
+
+ /**
+ * This error indicates that the telephone number is not correct or does not
+ * fit the dial plan rules.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_PHONE_NUMBER = 'ErrorInvalidPhoneNumber';
+
+ /**
+ * This error is returned if an invalid photo size is requested from the
+ * server.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_PHOTO_SIZE = 'ErrorInvalidPhotoSize';
+
+ /**
+ * This error occurs when the property that you are trying to append to does
+ * not support appending.
+ *
+ * The following are the only properties that support appending:
+ * - Recipient collections (ToRecipients, CcRecipients, BccRecipients)
+ * - Attendee collections (RequiredAttendees, OptionalAttendees, Resources)
+ * - Body
+ * - ReplyTo
+ *
+ * In addition, this error occurs when a message body is appended if the
+ * format specified in the request does not match the format of the item in
+ * the store.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_APPEND = 'ErrorInvalidPropertyAppend';
+
+ /**
+ * This error occurs if the delete operation is specified in an UpdateItem
+ * Operation or UpdateFolder Operation call for a property that does not
+ * support the delete operation.
+ *
+ * For example, you cannot delete the ItemId property of the ItemType
+ * object.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_DELETE = 'ErrorInvalidPropertyDelete';
+
+ /**
+ * This error occurs if the consumer passes in one of the flag properties in
+ * an Exists filter.
+ *
+ * For example, this error occurs if the IsRead or IsFromMe flags are
+ * specified in the Exists element. The request should use the IsEqualTo
+ * element instead for these as they are flags and therefore part of a
+ * single property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_FOR_EXISTS = 'ErrorInvalidPropertyForExists';
+
+ /**
+ * This error occurs when the property that you are trying to manipulate
+ * does not support the operation that is being performed on it.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_FOR_OPERATION = 'ErrorInvalidPropertyForOperation';
+
+ /**
+ * This error occurs if a property that is specified in the request is not
+ * available for the item type.
+ *
+ * For example, this error is returned if a property that is only available
+ * on calendar items is requested in a GetItem Operation call for a message
+ * or is updated in an UpdateItem Operation call for a message.
+ *
+ * This occurs in the following operations:
+ * - GetItem Operation
+ * - GetFolder Operation
+ * - UpdateItem Operation
+ * - UpdateFolder Operation
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_REQUEST = 'ErrorInvalidPropertyRequest';
+
+ /**
+ * This error indicates that the property that you are trying to manipulate
+ * does not support the operation that is being performed on it.
+ *
+ * For example, this error is returned if the property that you are trying
+ * to set is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_SET = 'ErrorInvalidPropertySet';
+
+ /**
+ * This error occurs when the state of a calendar item recurrence binary
+ * large object (BLOB) in the Exchange store is invalid.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_STATE = 'ErrorCalendarInvalidPropertyState';
+
+ /**
+ * This error occurs during an UpdateItem Operation when a client tries to
+ * update certain properties of a message that has already been sent.
+ *
+ * For example, the following properties cannot be updated on a sent
+ * message:
+ * - IsReadReceiptRequested
+ * - IsDeliveryReceiptRequested
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_UPDATE_SENT_MESSAGE = 'ErrorInvalidPropertyUpdateSentMessage';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROPERTY_VALUE = 'ErrorCalendarInvalidPropertyValue';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PROXY_SECURITY_CONTEXT = 'ErrorInvalidProxySecurityContext';
+
+ /**
+ * This error occurs if you call the GetEvents Operation or the Unsubscribe
+ * Operation by using a push subscription ID.
+ *
+ * To unsubscribe from a push subscription, you must respond to a push
+ * request with an unsubscribe response, or disconnect your Web service and
+ * wait for the push notifications to time out.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PULL_SUBSCRIPTION_ID = 'ErrorInvalidPullSubscriptionId';
+
+ /**
+ * This error is returned by the Subscribe Operation when it creates a
+ * "push" subscription and indicates that the URL that is included in the
+ * request is invalid.
+ *
+ * The following conditions must be met for Exchange Web Services to accept
+ * the URL:
+ * - String length > 0 and < 2083.
+ * - Protocol is http or https.
+ * - The URL can be parsed by the URI Microsoft .NET Framework class.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_PUSH_SUBSCRIPTION_URL = 'ErrorInvalidPushSubscriptionUrl';
+
+ /**
+ * This error indicates that the search folder has a recipient table filter
+ * that Exchange Web Services cannot represent.
+ *
+ * To get around this error, retrieve the folder without requesting the
+ * search parameters.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_RECIPIENT_SUBFILTER = 'ErrorInvalidRecipientSubfilter';
+
+ /**
+ * This error indicates that the search folder has a recipient table filter
+ * that Exchange Web Services cannot represent.
+ *
+ * To get around this error, retrieve the folder without requesting the
+ * search parameters.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_RECIPIENT_SUBFILTER_COMPARISON = 'ErrorInvalidRecipientSubfilterComparison';
+
+ /**
+ * This error indicates that the search folder has a recipient table filter
+ * that Exchange Web Services cannot represent.
+ *
+ * To get around this error, retrieve the folder without requesting the
+ * search parameters.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_RECIPIENT_SUBFILTER_ORDER = 'ErrorInvalidRecipientSubfilterOrder';
+
+ /**
+ * This error indicates that the search folder has a recipient table filter
+ * that Exchange Web Services cannot represent.
+ *
+ * To get around this error, retrieve the folder without requesting the
+ * search parameters.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_RECIPIENT_SUBFILTER_TEXT_FILTER = 'ErrorInvalidRecipientSubfilterTextFilter';
+
+ /**
+ * This error indicates that the recipient collection on your message or the
+ * attendee collection on your calendar item is invalid.
+ *
+ * For example, this error will be returned when an attempt is made to send
+ * an item that has no recipients.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_RECIPIENTS = 'ErrorInvalidRecipients';
+
+ /**
+ * This error occurs when the specified recurrence cannot be created.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_RECURRENCE = 'ErrorCalendarInvalidRecurrence';
+
+ /**
+ * This error is returned from the CreateItem Operation for Forward and
+ * Reply response objects when the referenced item is invalid.
+ *
+ * For example, this error may be returned in any of the following
+ * circumstances:
+ * - The referenced item identifier is not a Message, a CalendarItem, or a
+ * descendant of a Message or CalendarItem.
+ * - The reference item identifier is for a CalendarItem and the organizer
+ * is trying to Reply or ReplyAll to himself.
+ * - The message is a draft and Reply or ReplyAll is selected.
+ * - The reference item, for SuppressReadReceipt, is not a Message or a
+ * descendant of a Message.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_REFERENCE_ITEM = 'ErrorInvalidReferenceItem';
+
+ /**
+ * This error occurs when the SOAP request has a SOAP action header, but
+ * nothing in the SOAP body.
+ *
+ * Note that the SOAP Action header is not required as Exchange Web Services
+ * can determine the method to call from the local name of the root element
+ * in the SOAP body.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_REQUEST = 'ErrorInvalidRequest';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_RESTRICTION = 'ErrorInvalidRestriction';
+
+ /**
+ * Indicates that the retention tag GUID was invalid.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_RETENTION_TAG_ID_GUID = 'ErrorInvalidRetentionTagIdGuid';
+
+ /**
+ * This error is returned when an attempt is made to set an implicit tag on
+ * the PolicyTag property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_RETENTION_TAG_INHERITANCE = 'ErrorInvalidRetentionTagInheritance';
+
+ /**
+ * This error is returned when an attempt is made to set a nonexistent or
+ * invisible tag on a PolicyTag property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_RETENTION_TAG_INVISIBLE = 'ErrorInvalidRetentionTagInvisible';
+
+ /**
+ * This error indicates that no retention tags were found for this user.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_RETENTION_TAG_NONE = 'ErrorInvalidRetentionTagNone';
+
+ /**
+ * This error is returned when the specified retention tag has an incorrect
+ * action associated with it.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INVALID_RETENTION_TAG_TYPE_MISMATCH = 'ErrorInvalidRetentionTagTypeMismatch';
+
+ /**
+ * This error occurs if the routing type that is passed for an
+ * EmailAddressType is invalid.
+ *
+ * Typically, the routing type is set to Simple Mail Transfer Protocol
+ * (SMTP).
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_ROUTING_TYPE = 'ErrorInvalidRoutingType';
+
+ /**
+ * This error occurs if the specified duration end time is not greater than
+ * the start time, or if the end time does not occur in the future.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SCHEDULED_OOF_DURATION = 'ErrorInvalidScheduledOofDuration';
+
+ /**
+ * This error indicates that a proxy request that was sent to another server
+ * is not able to service the request due to a versioning mismatch.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_SCHEMA_VERSION_FOR_MAILBOX_VERSION = 'ErrorInvalidSchemaVersionForMailboxVersion';
+
+ /**
+ * This error indicates that the Exchange security descriptor on the
+ * Calendar folder in the store is corrupted.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SECURITY_DESCRIPTOR = 'ErrorInvalidSecurityDescriptor';
+
+ /**
+ * This error occurs during an attempt to send an item where the
+ * SavedItemFolderId is specified in the request but the SaveItemToFolder
+ * property is set to false.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SEND_ITEM_SAVE_SETTINGS = 'ErrorInvalidSendItemSaveSettings';
+
+ /**
+ * This error indicates that the token that was passed in the header is
+ * malformed, does not refer to a valid account in the directory, or is
+ * missing the primary group ConnectingSID.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SERIALIZED_ACCESS_TOKEN = 'ErrorInvalidSerializedAccessToken';
+
+ /**
+ * This error indicates that an invalid request server version was specified
+ * in the request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SERVER_VERSION = 'ErrorInvalidServerVersion';
+
+ /**
+ * This error indicates that the sharing metadata is not valid.
+ *
+ * This can be caused by invalid XML.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_SHARING_DATA = 'ErrorInvalidSharingData';
+
+ /**
+ * This error indicates that the sharing message is not valid.
+ *
+ * This can be caused by a missing property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_SHARING_MESSAGE = 'ErrorInvalidSharingMessage';
+
+ /**
+ * This error occurs when an invalid SID is passed in a request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SID = 'ErrorInvalidSid';
+
+ /**
+ * This error indicates that the SIP name, dial plan, or the phone number
+ * are invalid SIP URI.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_SIP_URI = 'ErrorInvalidSIPUri';
+
+ /**
+ * This error occurs when the SMTP address cannot be parsed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SMTP_ADDRESS = 'ErrorInvalidSmtpAddress';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SUBFILTER_TYPE = 'ErrorInvalidSubfilterType';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SUBFILTER_TYPE_NOT_ATTENDEE_TYPE = 'ErrorInvalidSubfilterTypeNotAttendeeType';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SUBFILTER_TYPE_NOT_RECIPIENT_TYPE = 'ErrorInvalidSubfilterTypeNotRecipientType';
+
+ /**
+ * This error indicates that the subscription is no longer valid.
+ *
+ * This could be because the Client Access server is restarting or because
+ * the subscription is expired.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SUBSCRIPTION = 'ErrorInvalidSubscription';
+
+ /**
+ * This error indicates that the subscribe request included multiple public
+ * folder IDs.
+ *
+ * A subscription can include multiple folders from the same mailbox or one
+ * public folder ID.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SUBSCRIPTION_REQUEST = 'ErrorInvalidSubscriptionRequest';
+
+ /**
+ * This error is returned by SyncFolderItems or SyncFolderHierarchy if the
+ * SyncState data that is passed is invalid.
+ *
+ * To fix this error, you must resynchronize without the sync state. Make
+ * sure that if you are persisting sync state BLOBs, you are not
+ * accidentally truncating the BLOB.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_SYNC_STATE_DATA = 'ErrorInvalidSyncStateData';
+
+ /**
+ * This error indicates that the specified time interval is invalid.
+ *
+ * The start time must be greater than or equal to the end time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_TIME_INTERVAL = 'ErrorInvalidTimeInterval';
+
+ /**
+ * This error occurs when an invalid time zone is encountered.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_TIMEZONE = 'ErrorCalendarInvalidTimeZone';
+
+ /**
+ * This error indicates that an internally inconsistent UserId was specified
+ * for a permissions operation.
+ *
+ * For example, if a distinguished user ID is specified (Default or
+ * Anonymous), this error is returned if you also try to specify a SID, or
+ * primary SMTP address or display name for this user.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_USER_INFO = 'ErrorInvalidUserInfo';
+
+ /**
+ * This error indicates that the user Out of Office (OOF) settings are
+ * invalid because of a missing internal or external reply.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_USER_OOF_SETTINGS = 'ErrorInvalidUserOofSettings';
+
+ /**
+ * This error occurs during Exchange Impersonation.
+ *
+ * The caller passed in an invalid UPN in the SOAP header that was not
+ * accessible in the directory.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_USER_PRINCIPAL_NAME = 'ErrorInvalidUserPrincipalName';
+
+ /**
+ * This error occurs when an invalid SID is passed in a request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_USER_SID = 'ErrorInvalidUserSid';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_USER_SID_MISSING_UPN = 'ErrorInvalidUserSidMissingUPN';
+
+ /**
+ * This error indicates that the comparison value in the restriction is
+ * invalid for the property you are comparing against.
+ *
+ * For example, the comparison value of DateTimeCreated > true would return
+ * this response code. This response code is also returned if you specify an
+ * enumeration property in the comparison, but the value that you are
+ * comparing against is not a valid value for that enumeration.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_VALUE_FOR_PROPERTY = 'ErrorInvalidValueForProperty';
+
+ /**
+ * This error is caused by an invalid watermark.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const INVALID_WATERMARK = 'ErrorInvalidWatermark';
+
+ /**
+ * This error indicates that a valid VoIP gateway is not available.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const IP_GATEWAY_NOT_FOUND = 'ErrorIPGatewayNotFound';
+
+ /**
+ * This error indicates that conflict resolution was unable to resolve
+ * changes for the properties.
+ *
+ * The items in the store may have been changed and have to be updated.
+ * Retrieve the updated change key and try again.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IRRESOLVABLE_CONFLICT = 'ErrorIrresolvableConflict';
+
+ /**
+ * This error indicates that the AcceptItem element is invalid for a
+ * calendar item that has been cancelled.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_CANCELLED_FOR_ACCEPT = 'ErrorCalendarIsCancelledForAccept';
+
+ /**
+ * This error indicates that the DeclineItem element is invalid for a
+ * calendar item that has been cancelled.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_CANCELLED_FOR_DECLINE = 'ErrorCalendarIsCancelledForDecline';
+
+ /**
+ * This error indicates that the RemoveItem element is invalid for a
+ * calendar item that has been cancelled.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_CANCELLED_FOR_REMOVE = 'ErrorCalendarIsCancelledForRemove';
+
+ /**
+ * This error indicates that the TentativelyAcceptItem element is invalid
+ * for a calendar item that has been cancelled.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_CANCELLED_FOR_TENTATIVE = 'ErrorCalendarIsCancelledForTentative';
+
+ /**
+ * This error indicates that the state of the object is corrupted and cannot
+ * be retrieved.
+ *
+ * When you are retrieving an item, only certain properties will be in this
+ * state, such as Body and MimeContent. Omit these properties and retry the
+ * operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_CORRUPT = 'ErrorItemCorrupt';
+
+ /**
+ * This error indicates that the AcceptItem element is invalid for a
+ * calendar item or meeting request in a delegated scenario.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ITEM_DELEGATED_FOR_ACCEPT = 'ErrorCalendarIsDelegatedForAccept';
+
+ /**
+ * This error indicates that the DeclineItem element is invalid for a
+ * calendar item or meeting request in a delegated scenario.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ITEM_DELEGATED_FOR_DECLINE = 'ErrorCalendarIsDelegatedForDecline';
+
+ /**
+ * This error indicates that the RemoveItem element is invalid for a meeting
+ * cancellation in a delegated scenario.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ITEM_DELEGATED_FOR_REMOVE = 'ErrorCalendarIsDelegatedForRemove';
+
+ /**
+ * This error indicates that the TentativelyAcceptItem element is invalid
+ * for a calendar item or meeting request in a delegated scenario.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const ITEM_DELEGATED_FOR_TENTATIVE = 'ErrorCalendarIsDelegatedForTentative';
+
+ /**
+ * This error occurs when the item was not found or you do not have
+ * permission to access the item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_NOT_FOUND = 'ErrorItemNotFound';
+
+ /**
+ * This error occurs if a property request on an item fails. The property
+ * may exist, but it could not be retrieved.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_PROPERTY_REQUEST_FAILED = 'ErrorItemPropertyRequestFailed';
+
+ /**
+ * This error occurs when attempts to save the item or folder fail.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_SAVE = 'ErrorItemSave';
+
+ /**
+ * This error occurs when attempts to save the item or folder fail because
+ * of invalid property values.
+ *
+ * The response code includes the path of the invalid properties.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_SAVE_PROPERTY_ERROR = 'ErrorItemSavePropertyError';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LEGACY_MAILBOX_FREE_BUSY_VIEW_TYPE_NOT_MERGED = 'ErrorLegacyMailboxFreeBusyViewTypeNotMerged';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LOCAL_SERVER_OBJECT_NOT_FOUND = 'ErrorLocalServerObjectNotFound';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const LOCATION_SERVICES_DISABLED = 'ErrorLocationServicesDisabled';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const LOCATION_SERVICES_INVALID_REQUEST = 'ErrorLocationServicesInvalidRequest';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const LOCATION_SERVICES_REQUEST_FAILED = 'ErrorLocationServicesRequestFailed';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const LOCATION_SERVICES_REQUEST_TIMED_OUT = 'ErrorLocationServicesRequestTimedOut';
+
+ /**
+ * This error indicates that the Availability service was unable to log on
+ * as the network service to proxy requests to the appropriate sites or
+ * forests.
+ *
+ * This response typically indicates a configuration error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const LOGON_AS_NETWORK_SERVICE_FAILED = 'ErrorLogonAsNetworkServiceFailed';
+
+ /**
+ * This error occurs if the MailboxData information cannot be mapped to a
+ * valid mailbox account.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAIL_RECIPIENT_NOT_FOUND = 'ErrorMailRecipientNotFound';
+
+ /**
+ * This error indicates that mail tips are disabled.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MAIL_TIPS_DISABLED = 'ErrorMailTipsDisabled';
+
+ /**
+ * This error indicates that the mailbox information in AD DS is configured
+ * incorrectly.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAILBOX_CONFIGURATION_ERROR = 'ErrorMailboxConfiguration';
+
+ /**
+ * This error indicates that the MailboxDataArray property in the request is
+ * empty.
+ *
+ * You must supply at least one mailbox identifier.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAILBOX_DATA_ARRAY_EMPTY = 'ErrorMailboxDataArrayEmpty';
+
+ /**
+ * This error occurs when more than 100 entries are supplied in a
+ * MailboxDataArray.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAILBOX_DATA_ARRAY_TOO_BIG = 'ErrorMailboxDataArrayTooBig';
+
+ /**
+ * This error indicates that an attempt to access a mailbox failed because
+ * the mailbox is in a failover process.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MAILBOX_FAILOVER = 'ErrorMailboxFailover';
+
+ /**
+ * Indicates that the mailbox hold was not found.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MAILBOX_HOLD_NOT_FOUND = 'ErrorMailboxHoldNotFound';
+
+ /**
+ * This error occurs when the connection to the mailbox to get the calendar
+ * view information failed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAILBOX_LOGON_FAILED = 'ErrorMailboxLogonFailed';
+
+ /**
+ * This error indicates that the mailbox is being moved to a different
+ * mailbox store or server.
+ *
+ * This error can also indicate that the mailbox is on another server or
+ * mailbox database.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAILBOX_MOVE_IN_PROGRESS = 'ErrorMailboxMoveInProgress';
+
+ /**
+ * This error is returned when a scoped search attempt is performed without
+ * using a QueryString (QueryStringType) element for a content indexing
+ * search.
+ *
+ * This is applicable to the SearchMailboxes and FindConversation
+ * operations.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MAILBOX_SCOPE_NOT_ALLOWED_WITHOUT_QUERY_STRING = 'ErrorMailboxScopeNotAllowedWithoutQueryString';
+
+ /**
+ * This error indicates that the mailbox store is unavailable for one of
+ * several reasons.
+ *
+ * These reasons include:
+ * - The mailbox store is corrupt.
+ * - The mailbox store is being stopped.
+ * - The mailbox store is offline.
+ * - A network error occurred when an attempt was made to access the mailbox
+ * store.
+ * - The mailbox store is overloaded and cannot accept any more connections.
+ * - The mailbox store has been paused.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAILBOX_STORE_UNAVAILABLE = 'ErrorMailboxStoreUnavailable';
+
+ /**
+ * This error occurs when the caller specifies an Id attribute that is
+ * malformed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MALFORMED_ID = 'ErrorInvalidIdMalformed';
+
+ /**
+ * This error occurs if the managed folder that you are trying to create
+ * already exists in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MANAGED_FOLDER_ALREADY_EXISTS = 'ErrorManagedFolderAlreadyExists';
+
+ /**
+ * This error occurs when the folder name that was specified in the request
+ * does not map to a managed folder definition in AD DS.
+ *
+ * You can only create instances of managed folders for folders that are
+ * defined in AD DS. Check the name and try again.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MANAGED_FOLDER_NOT_FOUND = 'ErrorManagedFolderNotFound';
+
+ /**
+ * This error indicates that the managed folders root was deleted from the
+ * mailbox or that a folder exists in the same parent folder that has the
+ * name of the managed folder root.
+ *
+ * This will also occur if the attempt to create the root managed folder
+ * fails.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MANAGED_FOLDERS_ROOT_FAILURE = 'ErrorManagedFoldersRootFailure';
+
+ /**
+ * This error indicates that a meeting request is out-of-date and cannot be
+ * updated.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_REQUEST_OUT_OF_DATE = 'ErrorCalendarMeetingRequestIsOutOfDate';
+
+ /**
+ * This error indicates that the suggestions engine encountered a problem
+ * when it was trying to generate the suggestions.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_SUGGESTION_GENERATION_FAILED = 'ErrorMeetingSuggestionGenerationFailed';
+
+ /**
+ * This error occurs if the MessageDisposition attribute is not set.
+ *
+ * This attribute is required for the following:
+ * - The CreateItem Operation and the UpdateItem Operation when the item
+ * being created or updated is a Message.
+ * - CancelCalendarItem, AcceptItem, DeclineItem, or TentativelyAcceptItem
+ * response objects.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_DISPOSITION_REQUIRED = 'ErrorMessageDispositionRequired';
+
+ /**
+ * This error indicates that the message that you are trying to send exceeds
+ * the allowed limits.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_SIZE_EXCEEDED = 'ErrorMessageSizeExceeded';
+
+ /**
+ * This error indicates that the given domain cannot be found.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MESSAGE_TRACKING_NO_SUCH_DOMAIN = 'ErrorMessageTrackingNoSuchDomain';
+
+ /**
+ * This error indicates that the message tracking service cannot track the
+ * message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MESSAGE_TRACKING_PERMANENT_ERROR = 'ErrorMessageTrackingPermanentError';
+
+ /**
+ * This error indicates that the message tracking service is either down or
+ * busy.
+ *
+ * This error code indicates a transient error. Clients can retry to connect
+ * to the server when this error is received.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MESSAGE_TRACKING_TRANSIENT_ERROR = 'ErrorMessageTrackingTransientError';
+
+ /**
+ * This error occurs when the MIME content is not a valid iCal for a
+ * CreateItem Operation.
+ *
+ * For a GetItem Operation, this response indicates that the MIME content
+ * could not be generated.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MIME_CONTENT_CONVERSATION_FAILED = 'ErrorMimeContentConversionFailed';
+
+ /**
+ * This error occurs when the MIME content is invalid.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MIME_CONTENT_INVALID = 'ErrorMimeContentInvalid';
+
+ /**
+ * This error occurs when the MIME content in the request is not a valid
+ * base 64 string.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MIME_CONTENT_INVALID_BASE_64_STRING = 'ErrorMimeContentInvalidBase64String';
+
+ /**
+ * This error MUST be returned when event notifications are missed.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MISSED_NOTIFICATION_EVENTS = 'ErrorMissedNotificationEvents';
+
+ /**
+ * This error indicates that a required argument was missing from the
+ * request.
+ *
+ * The response message text indicates which argument to check.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_ARGUMENT = 'ErrorMissingArgument';
+
+ /**
+ * This error indicates that you specified a distinguished folder ID in the
+ * request, but the account that made the request does not have a mailbox on
+ * the system.
+ *
+ * In that case, you must supply a Mailbox sub-element under
+ * DistinguishedFolderId.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_EMAIL_ADDRESS = 'ErrorMissingEmailAddress';
+
+ /**
+ * This error indicates that you specified a distinguished folder ID in the
+ * request, but the account that made the request does not have a mailbox on
+ * the system.
+ *
+ * In that case, you must supply a Mailbox sub-element under
+ * DistinguishedFolderId. This response is returned from the
+ * CreateManagedFolder Operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_EMAIL_ADDRESS_FOR_MANAGED_FOLDER = 'ErrorMissingEmailAddressForManagedFolder';
+
+ /**
+ * This error occurs if the EmailAddress element is missing.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_INFORMATION_EMAIL_ADDRESS = 'ErrorMissingInformationEmailAddress';
+
+ /**
+ * This error occurs if the ReferenceItemId is missing.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_INFORMATION_REFERENCE_ITEM_ID = 'ErrorMissingInformationReferenceItemId';
+
+ /**
+ * This error code is never returned.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MISSING_INFORMATION_SHARING_FOLDER_ID = 'ErrorMissingInformationSharingFolderId';
+
+ /**
+ * This error is returned when an attempt is made to not include the item
+ * element in the ItemAttachment element of a CreateAttachment Operation
+ * request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_ITEM_FOR_CREATE_ITEM_ATTACHMENT = 'ErrorMissingItemForCreateItemAttachment';
+
+ /**
+ * This error occurs when the policy IDs property, property tag 0x6732, for
+ * the folder is missing.
+ *
+ * You should consider this a corrupted folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_MANAGED_FOLDER_ID = 'ErrorMissingManagedFolderId';
+
+ /**
+ * This error indicates that you tried to send an item without including
+ * recipients.
+ *
+ * Note that if you call the CreateItem Operation with a message disposition
+ * that causes the message to be sent, you will get the following response
+ * code: ErrorInvalidRecipients.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_RECIPIENTS = 'ErrorMissingRecipients';
+
+ /**
+ * This error indicates that a UserId has not been fully specified in a
+ * permissions set.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MISSING_USER_ID_INFORMATION = 'ErrorMissingUserIdInformation';
+
+ /**
+ * This error indicates that you have specified more than one
+ * ExchangeImpersonation property value within a request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MORE_THAN_ONE_ACCESS_MODE_SPECIFIED = 'ErrorMoreThanOneAccessModeSpecified';
+
+ /**
+ * This error indicates that the move or copy operation failed.
+ *
+ * Moving occurs in the CreateItem Operation when you accept a meeting
+ * request that is in the Deleted Items folder. In addition, if you decline
+ * a meeting request, cancel a calendar item, or remove a meeting from your
+ * calendar, it is moved to the Deleted Items folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MOVE_COPY_FAILED = 'ErrorMoveCopyFailed';
+
+ /**
+ * This error occurs if you try to move a distinguished folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MOVE_DISTINGUISHED_FOLDER = 'ErrorMoveDistinguishedFolder';
+
+ /**
+ * This error occurs when a request attempts to access multiple mailbox
+ * servers.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MULTI_LEGACY_MAILBOX_ACCESS = 'ErrorMultiLegacyMailboxAccess';
+
+ /**
+ * This error occurs if the ResolveNames Operation returns more than one
+ * result or the ambiguous name that you specified matches more than one
+ * object in the directory.
+ *
+ * The response code includes the matched names in the response data.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NAME_RESOLUTION_MULTIPLE_RESULTS = 'ErrorNameResolutionMultipleResults';
+
+ /**
+ * This error indicates that the caller does not have a mailbox on the
+ * system.
+ *
+ * The ResolveNames Operation or ExpandDL Operation is invalid for
+ * connecting a user without a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NAME_RESOLUTION_NO_MAILBOX = 'ErrorNameResolutionNoMailbox';
+
+ /**
+ * This error indicates that the ResolveNames Operation returns no results.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NAME_RESOLUTION_NO_RESULTS = 'ErrorNameResolutionNoResults';
+
+ /**
+ * This error MUST be returned to the first subscription connection if a
+ * second subscription connection is opened.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NEW_EVENT_STREAM_CONNECTION_OPENED = 'ErrorNewEventStreamConnectionOpened';
+
+ /**
+ * This error code MUST be returned when the Web service cannot find a
+ * server to handle the request.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NO_APPLICABLE_PROXY_CAS_SERVERS_AVAILABLE = 'ErrorNoApplicableProxyCASServersAvailable';
+
+ /**
+ * This error occurs if there is no Calendar folder for the mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_CALENDAR = 'ErrorNoCalendar';
+
+ /**
+ * This error indicates that the request referred to a mailbox in another
+ * Active Directory site, but no Client Access servers in the destination
+ * site were configured for Windows Authentication, and therefore the
+ * request could not be proxied.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_DESTINATION_CAS_DUE_TO_KERBEROS_REQUIREMENTS = 'ErrorNoDestinationCASDueToKerberosRequirements';
+
+ /**
+ * This error indicates that the request referred to a mailbox in another
+ * Active Directory site, but no Client Access servers in the destination
+ * site were configured for SSL connections, and therefore the request could
+ * not be proxied.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_DESTINATION_CAS_DUE_TO_SSL_REQUIREMENTS = 'ErrorNoDestinationCASDueToSSLRequirements';
+
+ /**
+ * This error indicates that the request referred to a mailbox in another
+ * Active Directory site, but no Client Access servers in the destination
+ * site were of an acceptable product version to receive the request, and
+ * therefore the request could not be proxied.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_DESTINATION_CAS_DUE_TO_VERSION_MISMATCH = 'ErrorNoDestinationCASDueToVersionMismatch';
+
+ /**
+ * No error occurred for the request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_ERROR = 'NoError';
+
+ /**
+ * This error indicates that the caller tried to grant permissions in its
+ * calendar or contacts folder to a user in another organization, and the
+ * attempt failed.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NO_EXTERNAL_SHARING_ALLOWED_BY_POLICY = 'ErrorNotAllowedExternalSharingByPolicy';
+
+ /**
+ * This error occurs if you set the FolderClass property when you are
+ * creating an item other than a generic folder.
+ *
+ * For typed folders such as CalendarFolderType and TasksFolderType, the
+ * folder class is implied. Setting the folder class to a different folder
+ * type by using the UpdateFolder Operation results in the
+ * ErrorObjectTypeChanged response. Instead, use a generic folder type but
+ * set the folder class to the value that you require. Exchange Web Services
+ * will create the correct strongly typed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_FOLDER_CLASS_OVERRIDE = 'ErrorNoFolderClassOverride';
+
+ /**
+ * This error indicates that the caller does not have free/busy viewing
+ * rights on the Calendar folder in question.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_FREE_BUSY_ACCESS = 'ErrorNoFreeBusyAccess';
+
+ /**
+ * This error indicates that MAPI properties in the custom range, 0x8000 and
+ * greater, cannot be referenced by property tags.
+ *
+ * You must use the PropertySetId property or the DistinguishedPropertySetId
+ * property together with the PropertyName or PropertyId properties.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_PROPERTY_TAG_FOR_CUSTOM_PROPERTIES = 'ErrorNoPropertyTagForCustomProperties';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_PUBLIC_FOLDER_REPLICA_AVAILABLE = 'ErrorNoPublicFolderReplicaAvailable';
+
+ /**
+ * This error code MUST be returned if no public folder server is available
+ * or if the caller does not have a home public server.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NO_PUBLIC_FOLDER_SERVER_AVAILABLE = 'ErrorNoPublicFolderServerAvailable';
+
+ /**
+ * This error indicates that the request referred to a mailbox in another
+ * Active Directory site, but none of the Client Access servers in that site
+ * responded, and therefore the request could not be proxied.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_RESPONDING_CAS_IN_DESTINATION_SITE = 'ErrorNoRespondingCASInDestinationSite';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NO_SPEECH_DETECTED = 'ErrorNoSpeechDetected';
+
+ /**
+ * This error occurs when a mailbox could not be found for an email address.
+ *
+ * This error occurs in the following scenarios:
+ * - The e-mail address is empty in CreateManagedFolder.
+ * - The e-mail address does not refer to a valid account in a request that
+ * takes an e-mail address in the body or in the SOAP header, such as in an
+ * Exchange Impersonation call.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NON_EXISTENT_MAILBOX = 'ErrorNonExistentMailbox';
+
+ /**
+ * This error occurs when a caller passes in a non-primary SMTP address. The
+ * response includes the correct SMTP address to use.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NON_PRIMARY_SMTP_ADDRESS = 'ErrorNonPrimarySmtpAddress';
+
+ /**
+ * This error is returned whenever an ID that is not an item attachment ID
+ * is passed to a Web service method that expects an attachment ID.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOT_AN_ITEM_ATTACHMENT_ID = 'ErrorInvalidIdNotAnItemAttachmentId';
+
+ /**
+ * This error indicates that the user is not a delegate for the mailbox.
+ *
+ * It is returned by the GetDelegate Operation, the RemoveDelegate
+ * Operation, and the UpdateDelegate Operation when the specified delegate
+ * user is not found in the list of delegates.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const NOT_DELEGATE = 'ErrorNotDelegate';
+
+ /**
+ * This error indicates that the operation could not be completed because of
+ * insufficient memory.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOT_ENOUGH_MEMORY = 'ErrorNotEnoughMemory';
+
+ /**
+ * This error indicates that the operation (currently CancelItem) on the
+ * calendar item is not valid for an attendee; only the meeting organizer
+ * can cancel the meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOT_ORGANIZER = 'ErrorCalendarIsNotOrganizer';
+
+ /**
+ * This error occurs if the object type changed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OBJECT_TYPE_CHANGED = 'ErrorObjectTypeChanged';
+
+ /**
+ * This error occurs when the Start or End time of an occurrence is updated
+ * so that the occurrence is scheduled to happen earlier or later than the
+ * corresponding previous or next occurrence.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OCCURRENCE_CROSSING_BOUNDARY = 'ErrorOccurrenceCrossingBoundary';
+
+ /**
+ * This error indicates that the occurrence index does not point to an
+ * occurrence within the current recurrence.
+ *
+ * For example, if your recurrence pattern defines a set of three meeting
+ * occurrences and you try to access the fifth occurrence, this response
+ * code will result.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OCCURRENCE_INDEX_OUT_OF_RANGE = 'ErrorCalendarOccurrenceIndexIsOutOfRecurrenceRange';
+
+ /**
+ * This error indicates that any operation on a deleted occurrence
+ * (addressed via recurring master ID and occurrence index) is invalid.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OCCURRENCE_IS_DELETED = 'ErrorCalendarOccurrenceIsDeletedFromRecurrence';
+
+ /**
+ * This error indicates that the time allotment for a given occurrence
+ * overlaps with another occurrence of the same recurring item.
+ *
+ * This response also occurs when the length in minutes of a given
+ * occurrence is larger than Int32.MaxValue.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OCCURRENCE_TIME_SPAN_TOO_BIG = 'ErrorOccurrenceTimeSpanTooBig';
+
+ /**
+ * This error indicates that the current operation is not valid for the
+ * public folder root.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OPERATION_NOT_ALLOWED_WITH_PUBLIC_FOLDER_ROOT = 'ErrorOperationNotAllowedWithPublicFolderRoot';
+
+ /**
+ * This error indicates that the requester's organization is not federated
+ * so the requester cannot create sharing messages to send to an external
+ * user or cannot accept sharing messages received from an external user.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ORGANIZATION_NOT_FEDERATED = 'ErrorOrganizationNotFederated';
+
+ /**
+ * This error indicates that AcceptItem is invalid for the organizer’s
+ * calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ORGANIZER_FOR_ACCEPT = 'ErrorCalendarIsOrganizerForAccept';
+
+ /**
+ * This error indicates that DeclineItem is invalid for the organizer’s
+ * calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ORGANIZER_FOR_DECLINE = 'ErrorCalendarIsOrganizerForDecline';
+
+ /**
+ * This error indicates that RemoveItem is invalid for the organizer’s
+ * calendar item. To remove a meeting from the calendar, the organizer must
+ * use CancelItem.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ORGANIZER_FOR_REMOVE = 'ErrorCalendarIsOrganizerForRemove';
+
+ /**
+ * This error indicates that TentativelyAcceptItem is invalid for the
+ * organizer’s calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ORGANIZER_FOR_TENTATIVE = 'ErrorCalendarIsOrganizerForTentative';
+
+ /**
+ * This error MUST be returned when an attempt to manage Inbox rules occurs
+ * after another client has accessed the Inbox rules.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const OUTLOOK_RULE_BLOB_EXISTS = 'ErrorOutlookRuleBlobExists';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PARENT_FOLDER_ID_REQUIRED = 'ErrorParentFolderIdRequired';
+
+ /**
+ * This error occurs in the CreateFolder Operation when the parent folder is
+ * not found.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PARENT_FOLDER_NOT_FOUND = 'ErrorParentFolderNotFound';
+
+ /**
+ * This error indicates that you must change your password before you can
+ * access this mailbox.
+ *
+ * This occurs when a new account has been created and the administrator
+ * indicated that the user must change the password at first logon. You
+ * cannot update the password by using Exchange Web Services. You must use a
+ * tool such as Microsoft Office Outlook Web App to change your password.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PASSWORD_CHANGE_REQUIRED = 'ErrorPasswordChangeRequired';
+
+ /**
+ * This error indicates that the password has expired.
+ *
+ * You cannot change the password by using Exchange Web Services. You must
+ * use a tool such as Outlook Web App to change your password.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PASSWORD_EXPIRED = 'ErrorPasswordExpired';
+
+ /**
+ * This error indicates that the requester tried to grant permissions in its
+ * calendar or contacts folder to an external user but the sharing policy
+ * assigned to the requester indicates that the requested permission level
+ * is higher than what the sharing policy allows.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PERMISSION_NOT_ALLOWED_BY_POLICY = 'ErrorPermissionNotAllowedByPolicy';
+
+ /**
+ * This error Indicates that the telephone number was not in the correct
+ * form.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PHONE_NUMBER_NOT_DIALABLE = 'ErrorPhoneNumberNotDialable';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PROMPT_PUBLISHING_OPERATION_FAILED = 'ErrorPromptPublishingOperationFailed';
+
+ /**
+ * This error indicates that the update failed because of invalid property
+ * values.
+ *
+ * The response message includes the invalid property paths.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROPERTY_UPDATE_ERROR = 'ErrorPropertyUpdate';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROPERTY_VALIDATION_FAILURE = 'ErrorPropertyValidationFailure';
+
+ /**
+ * This error indicates that the request referred to a subscription that
+ * exists on another Client Access server, but an attempt to proxy the
+ * request to that Client Access server failed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROXIED_SUBSCRIPTION_CALL_FAILURE = 'ErrorProxiedSubscriptionCallFailure';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROXY_CALL_FAILED = 'ErrorProxyCallFailed';
+
+ /**
+ * This error indicates that the request referred to a mailbox in another
+ * Active Directory site, and the original caller is a member of more than
+ * 3,000 groups.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROXY_GROUP_SID_LIMIT_EXCEEDED = 'ErrorProxyGroupSidLimitExceeded';
+
+ /**
+ * This error indicates that the request that Exchange Web Services sent to
+ * another Client Access server when trying to fulfill a GetUserAvailability
+ * request was invalid.
+ *
+ * This response code typically indicates that a configuration or rights
+ * error has occurred, or that someone tried unsuccessfully to mimic an
+ * availability proxy request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROXY_REQUEST_NOT_ALLOWED = 'ErrorProxyRequestNotAllowed';
+
+ /**
+ * This error indicates that Exchange Web Services tried to proxy an
+ * availability request to another Client Access server for fulfillment, but
+ * the request failed.
+ *
+ * This response can be caused by network connectivity issues or request
+ * timeout issues.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROXY_REQUEST_PROCESSING_FAILED = 'ErrorProxyRequestProcessingFailed';
+
+ /**
+ * This error code must be returned if the Web service cannot determine
+ * whether the request is to run on the target server or will be proxied to
+ * another server.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PROXY_SERVICE_DISCOVERY_FAILED = 'ErrorProxyServiceDiscoveryFailed';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PROXY_TOKEN_EXPIRED = 'ErrorProxyTokenExpired';
+
+ /**
+ * This error occurs when the public folder mailbox URL cannot be found.
+ *
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PUBLIC_FOLDER_MAILBOX_DISCOVERY_FAILED = 'ErrorPublicFolderMailboxDiscoveryFailed';
+
+ /**
+ * This error occurs when an attempt is made to access a public folder and
+ * the attempt is unsuccessful.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PUBLIC_FOLDER_OPERATION_FAILED = 'ErrorPublicFolderOperationFailed';
+
+ /**
+ * This error occurs when the recipient that was passed to the
+ * GetUserAvailability Operation is located on a computer that is running a
+ * version of Exchange Server that is earlier than Exchange 2007, and the
+ * request to retrieve free/busy information for the recipient from the
+ * public folder server failed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PUBLIC_FOLDER_REQUEST_PROCESSING_FAILED = 'ErrorPublicFolderRequestProcessingFailed';
+
+ /**
+ * This error occurs when the recipient that was passed to the
+ * GetUserAvailability Operation is located on a computer that is running a
+ * version of Exchange Server that is earlier than Exchange 2007, and the
+ * request to retrieve free/busy information for the recipient from the
+ * public folder server failed because the organizational unit did not have
+ * an associated public folder server.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PUBLIC_FOLDER_SERVER_NOT_FOUND = 'ErrorPublicFolderServerNotFound';
+
+ /**
+ * This error occurs when a synchronization operation succeeds against the
+ * primary public folder mailbox but does not succeed against the secondary
+ * public folder mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PUBLIC_FOLDER_SYNC_EXCEPTION = 'ErrorPublicFolderSyncException';
+
+ /**
+ * This error indicates that the search folder restriction may be valid, but
+ * it is not supported by EWS.
+ *
+ * Exchange Web Services limits restrictions to contain a maximum of 255
+ * filter expressions. If you try to bind to an existing search folder that
+ * exceeds 255, this response code is returned.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const QUERY_FILTER_TOO_LONG = 'ErrorQueryFilterTooLong';
+
+ /**
+ * This error occurs when the mailbox quota is exceeded.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const QUOTA_EXCEEDED = 'ErrorQuotaExceeded';
+
+ /**
+ * This error is returned by the GetEvents Operation or push notifications
+ * when a failure occurs while retrieving event information.
+ *
+ * When this error is returned, the subscription is deleted. Re-create the
+ * event synchronization based on a last known watermark.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const READ_EVENTS_FAILED = 'ErrorReadEventsFailed';
+
+ /**
+ * This error is returned by the CreateItem Operation if an attempt was made
+ * to suppress a read receipt when the message sender did not request a read
+ * receipt on the message or if the message is in the Junk E-mail folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const READ_RECEIPT_NOT_PENDING = 'ErrorReadReceiptNotPending';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const RECIPIENT_NOT_FOUND = 'ErrorRecipientNotFound';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const RECOGNIZER_NOT_INSTALLED = 'ErrorRecognizerNotInstalled';
+
+ /**
+ * This error occurs when the end date for the recurrence is after 9/1/4500.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_END_DATE_TOO_BIG = 'ErrorRecurrenceEndDateTooBig';
+
+ /**
+ * This error occurs when the specified recurrence does not have any
+ * occurrence instances in the specified range.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RECURRENCE_HAS_NO_OCCURRENCE = 'ErrorRecurrenceHasNoOccurrence';
+
+ /**
+ * This error indicates that the delegate list failed to be saved after
+ * delegates were removed.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const REMOVE_DELEGATES_FAILED = 'ErrorRemoveDelegatesFailed';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const REQUEST_ABORTED = 'ErrorRequestAborted';
+
+ /**
+ * This error occurs when the request stream is larger than 400 KB.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const REQUEST_STREAM_TOO_BIG = 'ErrorRequestStreamTooBig';
+
+ /**
+ * This error is returned when a required property is missing in a
+ * CreateAttachment Operation request.
+ *
+ * The missing property URI is included in the response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const REQUIRED_PROPERTY_MISSING = 'ErrorRequiredPropertyMissing';
+
+ /**
+ * This error indicates that the caller has specified a folder that is not a
+ * contacts folder to the ResolveNames Operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESOLVE_NAMES_INVALID_FOLDER_TYPE = 'ErrorResolveNamesInvalidFolderType';
+
+ /**
+ * This error indicates that the caller has specified more than one contacts
+ * folder to the ResolveNames Operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESOLVE_NAMES_ONLY_ONE_CONTACTS_FOLDER_ALLOWED = 'ErrorResolveNamesOnlyOneContactsFolderAllowed';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESPONSE_SCHEMA_VALIDATION = 'ErrorResponseSchemaValidation';
+
+ /**
+ * This error occurs when the restriction cannot be evaluated by Exchange
+ * Web Services.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESTRICTION_TOO_COMPLEX = 'ErrorRestrictionTooComplex';
+
+ /**
+ * This error occurs if the restriction contains more than 255 nodes.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESTRICTION_TOO_LONG = 'ErrorRestrictionTooLong';
+
+ /**
+ * This error indicates that the number of calendar entries for a given
+ * recipient exceeds the allowed limit of 1000.
+ *
+ * Reduce the window and try again.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const RESULT_SET_TOO_BIG = 'ErrorResultSetTooBig';
+
+ /**
+ * This error MUST be returned when a user's rule quota has been exceeded.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RULES_OVER_QUOTA = 'ErrorRulesOverQuota';
+
+ /**
+ * This error occurs when the SavedItemFolderId is not found.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SAVED_ITEM_FOLDER_NOT_FOUND = 'ErrorSavedItemFolderNotFound';
+
+ /**
+ * This error occurs when the request cannot be validated against the
+ * schema.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SCHEMA_VALIDATION = 'ErrorSchemaValidation';
+
+ /**
+ * This error indicates that the search folder was created, but the search
+ * criteria were never set on the folder.
+ *
+ * This only occurs when you access corrupted search folders that were
+ * created by using another API or client. To fix this error, use the
+ * UpdateFolder Operation to set the SearchParameters to include the
+ * restriction that should be on the folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEARCH_FOLDER_NOT_INITIALIZED = 'ErrorSearchFolderNotInitialized';
+
+ /**
+ * This error is returned when an unexpected photo size is requested in a
+ * GetUserPhoto operation request.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SEARCH_QUERY_HAS_TOO_MANY_KEYWORDS = 'ErrorSearchQueryHasTooManyKeywords';
+
+ /**
+ * This error is returned when a SearchMailboxes operation request contains
+ * too many mailboxes to search.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SEARCH_TOO_MANY_MAILBOXES = 'ErrorSearchTooManyMailboxes';
+
+ /**
+ * This error occurs when a an attempt to send a message as another user is
+ * denied.
+ *
+ * The request will be denied when both of the following conditions occur:
+ * - A user has been granted CanActAsOwner permissions but is not granted
+ * delegate rights on the principal’s mailbox.
+ * - The same user tries to create and send an e-mail message in the
+ * principal’s mailbox by using the SendAndSaveCopy option.
+ *
+ * The result is an ErrorSendAsDenied error and the creation of the e-mail
+ * message in the principal’s Drafts folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_AS_DENIED = 'ErrorSendAsDenied';
+
+ /**
+ * This error is returned by the DeleteItem Operation if the
+ * SendMeetingCancellations attribute is missing from the request and the
+ * item to delete is a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_MEETING_CANCELLATIONS_REQUIRED = 'ErrorSendMeetingCancellationsRequired';
+
+ /**
+ * This error is returned by the UpdateItem Operation if the
+ * SendMeetingInvitationsOrCancellations attribute is missing from the
+ * request and the item to update is a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_MEETING_INVITATIONS_OR_CANCELLATIONS_REQUIRED = 'ErrorSendMeetingInvitationsOrCancellationsRequired';
+
+ /**
+ * This error is returned by the CreateItem Operation if the
+ * SendMeetingInvitations attribute is missing from the request and the item
+ * to create is a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SEND_MEETING_INVITATIONS_REQUIRED = 'ErrorSendMeetingInvitationsRequired';
+
+ /**
+ * This error indicates that after the organizer sends a meeting request,
+ * the request cannot be updated.
+ *
+ * To modify the meeting, modify the calendar item, not the meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SENT_MEETING_REQUEST_UPDATE = 'ErrorSentMeetingRequestUpdate';
+
+ /**
+ * This error indicates that after the task initiator sends a task request,
+ * that request cannot be updated.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SENT_TASK_REQUEST_UPDATE = 'ErrorSentTaskRequestUpdate';
+
+ /**
+ * This error occurs when the server is busy.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SERVER_BUSY = 'ErrorServerBusy';
+
+ /**
+ * This error indicates that Exchange Web Services tried to proxy a user
+ * availability request to the appropriate forest for the recipient, but it
+ * could not determine where to send the request because of a service
+ * discovery failure.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SERVICE_DISCOVERY_FAILED = 'ErrorServiceDiscoveryFailed';
+
+ /**
+ * This error indicates that the sharing message is not supported.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SHARING_MESSAGE_NOT_SUPPORTED = 'ErrorNotSupportedSharingMessage';
+
+ /**
+ * This error indicates that the external URL property has not been set in
+ * the Active Directory database.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SHARING_NO_EXTERNAL_EWS_AVAILABLE = 'ErrorSharingNoExternalEwsAvailable';
+
+ /**
+ * This error indicates that an attempt at synchronizing a sharing folder
+ * failed.
+ *
+ * This error code is returned when one of the following occurs:
+ * - The subscription for a sharing folder is not found.
+ * - The sharing folder is not found
+ * - The corresponding directory user is not found
+ * - The user no longer exists.
+ * - The appointment is invalid
+ * - The contact item is invalid.
+ * - There is a communication failure with the remote server.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SHARING_SYNCHRONIZATION_FAILED = 'ErrorSharingSynchronizationFailed';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const SPEECH_GRAMMAR_ERROR = 'ErrorSpeechGrammarError';
+
+ /**
+ * This error occurs in an UpdateItem Operation or a SendItem Operation when
+ * the change key is not up-to-date or was not supplied.
+ *
+ * Call the GetItem Operation to retrieve an updated change key and then try
+ * the operation again.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const STALE_OBJECT = 'ErrorStaleObject';
+
+ /**
+ * This error occurs when the caller specifies an Id attribute that is too
+ * long.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const STORE_OBJECT_ID_TOO_LONG = 'ErrorInvalidIdStoreObjectIdTooLong';
+
+ /**
+ * This error Indicates that a user cannot immediately send more requests
+ * because the submission quota has been reached.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SUBMISSION_QUOTE_EXCEEDED = 'ErrorSubmissionQuotaExceeded';
+
+ /**
+ * This error occurs when you try to access a subscription by using an
+ * account that did not create that subscription.
+ *
+ * Each subscription can only be accessed by the creator of the
+ * subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SUBSCRIPTION_ACCESS_DENIED = 'ErrorSubscriptionAccessDenied';
+
+ /**
+ * This error indicates that you cannot create a subscription if you are not
+ * the owner or do not have owner access to the mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const SUBSCRIPTION_DELEGATE_ACCESS_NOT_SUPPORTED = 'ErrorSubscriptionDelegateAccessNotSupported';
+
+ /**
+ * This error occurs if the subscription that corresponds to the specified
+ * SubscriptionId is not found.
+ *
+ * The subscription may have expired, the Exchange Web Services process may
+ * have been restarted, or an invalid subscription was passed in. If the
+ * subscription was valid, re-create the subscription with the latest
+ * watermark. This is returned by the Unsubscribe Operation or the GetEvents
+ * Operation responses.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SUBSCRIPTION_NOT_FOUND = 'ErrorSubscriptionNotFound';
+
+ /**
+ * This error code must be returned when a request is made for a
+ * subscription that has been unsubscribed.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SUBSCRIPTION_UNSUBSCRIBED = 'ErrorSubscriptionUnsubsribed';
+
+ /**
+ * This error is returned by the SyncFolderItems Operation if the parent
+ * folder that is specified cannot be found.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SYNC_FOLDER_NOT_FOUND = 'ErrorSyncFolderNotFound';
+
+ /**
+ * This error code is not used.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TEAM_MAILBOX_ACTIVE_TO_PENDING_DELETE = 'ErrorTeamMailboxActiveToPendingDelete';
+
+ /**
+ * This error indicates a general error that can occur when trying to access
+ * a team mailbox.
+ *
+ * Try submitting the request at a later time.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TEAM_MAILBOX_ERROR_UNKNOWN = 'ErrorTeamMailboxErrorUnknown';
+
+ /**
+ * This error indicates that an attempt to send a notification to the team
+ * mailbox owners was unsuccessful.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TEAM_MAILBOX_FAILED_SENDING_NOTIFICATIONS = 'ErrorTeamMailboxFailedSendingNotifications';
+
+ /**
+ * This error code is not used.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TEAM_MAILBOX_NOT_AUTHORIZED_OWNER = 'ErrorTeamMailboxNotAuthorizedOwner';
+
+ /**
+ * This error indicates that a team mailbox was not found.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TEAM_MAILBOX_NOT_FOUND = 'ErrorTeamMailboxNotFound';
+
+ /**
+ * This error indicates that a team mailbox was found but that it is not
+ * linked to a SharePoint Server.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TEAM_MAILBOX_NOT_LINKED_TO_SHARE_POINT = 'ErrorTeamMailboxNotLinkedToSharePoint';
+
+ /**
+ * This error indicates that a team mailbox was found but that the link to
+ * the SharePoint Server is not valid.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TEAM_MAILBOX_URL_VALIDATION_FAILED = 'ErrorTeamMailboxUrlValidationFailed';
+
+ /**
+ * This error indicates that the time window that was specified is larger
+ * than the allowed limit.
+ *
+ * By default, the allowed limit is 42.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TIME_INTERVAL_TOO_BIG = 'ErrorTimeIntervalTooBig';
+
+ /**
+ * This error indicates that there is a time zone error.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TIME_ZONE_ERROR = 'ErrorTimeZone';
+
+ /**
+ * This error occurs when there is not enough time to complete the
+ * processing of the request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TIMEOUT_EXPIRED = 'ErrorTimeoutExpired';
+
+ /**
+ * This error indicates that the destination folder does not exist.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TO_FOLDER_NOT_FOUND = 'ErrorToFolderNotFound';
+
+ /**
+ * This error occurs if the caller tries to do a Token serialization request
+ * but does not have the ms-Exch-EPI-TokenSerialization right on the Client
+ * Access server.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TOKEN_SERIALIZATION_DENIED = 'ErrorTokenSerializationDenied';
+
+ /**
+ * This error is returned when the attachment hierarchy on an item exceeds
+ * the maximum of 255 levels deep.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TOO_MANY_ATTACHMENT_LEVELS = 'ErrorInvalidIdTooManyAttachmentLevels';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const UM_SERVER_UNAVAILABLE = 'ErrorUMServerUnavailable';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNABLE_TO_GET_USER_OOF_SETTINGS = 'ErrorUnableToGetUserOofSettings';
+
+ /**
+ * This error occurs when an unsuccessful attempt is made to remove an IM
+ * contact from a group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const UNABLE_TO_REMOVE_IM_CONTACT_FROM_GROUP = 'ErrorUnableToRemoveImContactFromGroup';
+
+ /**
+ * This error indicates that a user's dial plan is not available.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNIFIED_MESSAGING_DIAL_PLAN_NOT_FOUND = 'ErrorUnifiedMessagingDialPlanNotFound';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const UNIFIED_MESSAGING_PROMPT_NOT_FOUND = 'ErrorUnifiedMessagingPromptNotFound';
+
+ /**
+ * This error is intended for internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const UNIFIED_MESSAGING_REPORT_DATA_NOT_FOUND = 'ErrorUnifiedMessagingReportDataNotFound';
+
+ /**
+ * This error indicates that the user could not be found.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNIFIED_MESSAGING_REQUEST_FAILED = 'ErrorUnifiedMessagingRequestFailed';
+
+ /**
+ * This error indicates that a valid server for the dial plan could not be
+ * found to handle the request.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNIFIED_MESSAGING_SERVER_NOT_FOUND = 'ErrorUnifiedMessagingServerNotFound';
+
+ /**
+ * This error occurs when you try to set the Culture property to a value
+ * that is not parsable by the System.Globalization.CultureInfo class.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_CULTURE = 'ErrorUnsupportedCulture';
+
+ /**
+ * This error occurs when a caller tries to use extended properties of types
+ * object, object array, error, or null.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_MAPI_PROPERTY_TYPE = 'ErrorUnsupportedMapiPropertyType';
+
+ /**
+ * This error occurs when you are trying to retrieve or set MIME content for
+ * an item other than a PostItemType, MessageType, or CalendarItemType
+ * object.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_MIME_CONVERSION = 'ErrorUnsupportedMimeConversion';
+
+ /**
+ * This error occurs when the caller passes a property that is invalid for a
+ * query.
+ *
+ * This can occur when calculated properties are used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_PATH_FOR_QUERY = 'ErrorUnsupportedPathForQuery';
+
+ /**
+ * This error occurs when the caller passes a property that is invalid for a
+ * sort or group by property.
+ *
+ * This can occur when calculated properties are used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_PATH_FOR_SORT_GROUP = 'ErrorUnsupportedPathForSortGroup';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_PROPERTY_DEFINITION = 'ErrorUnsupportedPropertyDefinition';
+
+ /**
+ * This error indicates that the search folder restriction may be valid, but
+ * it is not supported by EWS.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_QUERY_FILTER = 'ErrorUnsupportedQueryFilter';
+
+ /**
+ * This error indicates that the specified recurrence is not supported for
+ * tasks.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_RECURRENCE = 'ErrorUnsupportedRecurrence';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_SUBFILTER = 'ErrorUnsupportedSubFilter';
+
+ /**
+ * This error indicates that Exchange Web Services found a property type in
+ * the store but it cannot generate XML for the property type.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUPPORTED_TYPE_FOR_CONVERSION = 'ErrorUnsupportedTypeForConversion';
+
+ /**
+ * This error indicates that the delegate list failed to be saved after
+ * delegates were updated.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ const UPDATE_DELEGATES_FAILED = 'ErrorUpdateDelegatesFailed';
+
+ /**
+ * This error occurs when the single property path that is listed in a
+ * change description does not match the single property that is being set
+ * within the actual ItemType or FolderType object.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UPDATE_PROPERTY_MISMATCH = 'ErrorUpdatePropertyMismatch';
+
+ /**
+ * This error indicates that the requester tried to grant permissions in its
+ * calendar or contacts folder to an external user but the sharing policy
+ * assigned to the requester indicates that the domain of the external user
+ * is not listed in the policy.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const USER_NOT_ALLOWED_BY_POLICY = 'ErrorUserNotAllowedByPolicy';
+
+ /**
+ * This error indicates that the requester is not enabled.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const USER_NOT_UNIFIED_MESSAGING_ENABLED = 'ErrorUserNotUnifiedMessagingEnabled';
+
+ /**
+ * Indicates that the requester's organization has a set of federated
+ * domains but the requester's organization does not have any SMTP proxy
+ * addresses with one of the federated domains.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const USER_WITHOUT_FEDERATED_PROXY_ADDRESS = 'ErrorUserWithoutFederatedProxyAddress';
+
+ /**
+ * This error indicates that a calendar view start date or end date was set
+ * to 1/1/0001 12:00:00 AM or 12/31/9999 11:59:59 PM.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const VALUE_OUT_OF_RANGE = 'ErrorValueOutOfRange';
+
+ /**
+ * This error occurs when Start to End range for the CalendarView element is
+ * more than the maximum allowed, currently 2 years.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const VIEW_RANGE_TOO_BIG = 'ErrorCalendarViewRangeTooBig';
+
+ /**
+ * This error indicates that the Exchange store detected a virus in the
+ * message.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const VIRUS_DETECTED = 'ErrorVirusDetected';
+
+ /**
+ * This error indicates that the Exchange store detected a virus in the
+ * message and deleted it.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const VIRUS_MESSAGE_DELETED = 'ErrorVirusMessageDeleted';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const VOICE_MAIL_NOT_IMPLEMENTED = 'ErrorVoiceMailNotImplemented';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WEB_REQUEST_IN_INVALID_STATE = 'ErrorWebRequestInInvalidState';
+
+ /**
+ * This error indicates that there was an internal failure during
+ * communication with unmanaged code.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WIN32_INTEROP_ERROR = 'ErrorWin32InteropError';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WORKING_HOURS_SAVE_FAILED = 'ErrorWorkingHoursSaveFailed';
+
+ /**
+ * This response code is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WORKING_HOURS_XML_MALFORMED = 'ErrorWorkingHoursXmlMalformed';
+
+ /**
+ * This error indicates that a request can only be made to a server that is
+ * the same version as the mailbox server.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const WRONG_SERVER_VERSION = 'ErrorWrongServerVersion';
+
+ /**
+ * This error indicates that a request was made by a delegate that has a
+ * different server version than the principal's mailbox server.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const WRONG_SERVER_VERSION_DELEGATE = 'ErrorWrongServerVersionDelegate';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseTypeType.php
new file mode 100644
index 00000000..3329465f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ResponseTypeType.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ResponseTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Identifies the type of a response that is received.
+ *
+ * @package php-ews\Enumeration
+ */
+class ResponseTypeType extends Enumeration
+{
+ /**
+ * Response type indicating that a request has been accepted.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACCEPT = 'Accept';
+
+ /**
+ * Response type indicating that a request has been declined.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DECLINE = 'Decline';
+
+ /**
+ * Response type indicating that no response has been received.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NONE = 'NoResponseReceived';
+
+ /**
+ * Response type indicating that the attendee is the organizer.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ORGANIZER = 'Organizer';
+
+ /**
+ * Response type indicating that a request has been tentatively accepted.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TENTATIVE = 'Tentative';
+
+ /**
+ * Response type indicating that the response is unknown.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNKNOWN = 'Unknown';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RetentionActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RetentionActionType.php
new file mode 100644
index 00000000..285ad7bc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RetentionActionType.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\RetentionActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the action performed on items with the retention tag.
+ *
+ * @package php-ews\Enumeration
+ */
+class RetentionActionType extends Enumeration
+{
+ /**
+ * The item is deleted and put into the Dumpster.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DELETE_AND_ALLOW_RECOVERY = 'DeleteAndAllowRecovery';
+
+ /**
+ * The item is marked as having exceeded the retention time limit.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MARK_AS_PAST_RETENTION_LIMIT = 'MarkAsPastRetentionLimit';
+
+ /**
+ * The item is moved to the archive mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MOVE_TO_ARCHIVE = 'MoveToArchive';
+
+ /**
+ * The item is moved to the default Deleted Items folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MOVE_TO_DELETED_ITEMS = 'MoveToDeletedItems';
+
+ /**
+ * The item is moved to a specified folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MOVE_TO_FOLDER = 'MoveToFolder';
+
+ /**
+ * No action is performed on the item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NONE = 'None';
+
+ /**
+ * The item is permanently deleted from the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERMANENTLY_DELETE = 'PermanentlyDelete';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RoutingType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RoutingType.php
new file mode 100644
index 00000000..ad094bb4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RoutingType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\RoutingType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the routing protocol for a recipient.
+ *
+ * @package php-ews\Enumeration
+ */
+class RoutingType extends Enumeration
+{
+ /**
+ * Route the email using the SMTP protocol.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SMTP = 'SMTP';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleFieldURIType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleFieldURIType.php
new file mode 100644
index 00000000..344a3a3b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleFieldURIType.php
@@ -0,0 +1,826 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\RuleFieldURIType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the URI to the rule field that caused a validation error.
+ *
+ * @package php-ews\Enumeration
+ */
+class RuleFieldURIType extends Enumeration
+{
+ /**
+ * Specifies the Action:AssignCategories field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_ASSIGN_CATEGORIES = 'Action:AssignCategories';
+
+ /**
+ * Specifies the Action:CopyToFolder field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_COPY_TO_FOLDER = 'Action:CopyToFolder';
+
+ /**
+ * Specifies the Action:Delete field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_DELETE = 'Action:Delete';
+
+ /**
+ * Specifies the Action:ForwardAsAttachmentToRecipients field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_FORWARD_AS_ATTACHMENT_TO_RECIPIENTS = 'Action:ForwardAsAttachmentToRecipients';
+
+ /**
+ * Specifies the Action:ForwardToRecipients field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_FORWARD_TO_RECIPIENTS = 'Action:ForwardToRecipients';
+
+ /**
+ * Specifies the Action:MarkAsRead field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_MARK_AS_READ = 'Action:MarkAsRead';
+
+ /**
+ * Specifies the Action:MarkImportance field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_MARK_IMPORTANCE = 'Action:MarkImportance';
+
+ /**
+ * Specifies the Action:MoveToFolder field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_MOVE_TO_FOLDER = 'Action:MoveToFolder';
+
+ /**
+ * Specifies the Action:PermanentDelete field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_PERMANENT_DELETE = 'Action:PermanentDelete';
+
+ /**
+ * Specifies the Action:RedirectToRecipients field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_REDIRECT_TO_RECIPIENTS = 'Action:RedirectToRecipients';
+
+ /**
+ * Specifies the Action:SendSMSAlertToRecipients field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_SEND_SMS_ALERT_TO_RECIPIENTS = 'Action:SendSMSAlertToRecipients';
+
+ /**
+ * Specifies the Action:ServerReplyWithMessage field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_SERVER_REPLY_WITH_MESSAGE = 'Action:ServerReplyWithMessage';
+
+ /**
+ * Specifies the Action:StopProcessingRules field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTION_STOP_PROCESSING_RULES = 'Action:StopProcessingRules';
+
+ /**
+ * Specifies the Actions field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ACTIONS = 'Actions';
+
+ /**
+ * Specifies the Condition:Categories field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_CATEGORIES = 'Condition:Categories';
+
+ /**
+ * Specifies the Condition:ContainsBodyStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_CONTAINS_BODY_STRINGS = 'Condition:ContainsBodyStrings';
+
+ /**
+ * Specifies the Condition:ContainsHeaderStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_CONTAINS_HEADER_STRINGS = 'Condition:ContainsHeaderStrings';
+
+ /**
+ * Specifies the Condition:ContainsRecipientStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_CONTAINS_RECIPIENT_STRINGS = 'Condition:ContainsRecipientStrings';
+
+ /**
+ * Specifies the Condition:ContainsSenderStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_CONTAINS_SENDER_STRINGS = 'Condition:ContainsSenderStrings';
+
+ /**
+ * Specifies the Condition:ContainsSubjectOrBodyStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_CONTAINS_SUBJECT_OR_BODY_STRINGS = 'Condition:ContainsSubjectOrBodyStrings';
+
+ /**
+ * Specifies the Condition:ContainsSubjectStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_CONTAINS_SUBJECT_STRINGS = 'Condition:ContainsSubjectStrings';
+
+ /**
+ * Specifies the Condition:FlaggedForAction field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_FLAGGED_FOR_ACTION = 'Condition:FlaggedForAction';
+
+ /**
+ * Specifies the Condition:FromAddresses field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_FROM_ADDRESSES = 'Condition:FromAddresses';
+
+ /**
+ * Specifies the Condition:FromConnectedAccounts field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_FROM_CONNECTED_ACCOUNTS = 'Condition:FromConnectedAccounts';
+
+ /**
+ * Specifies the Condition:HasAttachments field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_HAS_ATTACHMENTS = 'Condition:HasAttachments';
+
+ /**
+ * Specifies the Condition:Importance field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IMPORTANCE = 'Condition:Importance';
+
+ /**
+ * Specifies the Condition:IsApprovalRequest field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_APPROVAL_REQUEST = 'Condition:IsApprovalRequest';
+
+ /**
+ * Specifies the Condition:IsAutomaticForward field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_AUTOMATIC_FORWARD = 'Condition:IsAutomaticForward';
+
+ /**
+ * Specifies the Condition:IsAutomaticReply field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_AUTOMATIC_REPLY = 'Condition:IsAutomaticReply';
+
+ /**
+ * Specifies the Condition:IsEncrypted field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_ENCRYPTED = 'Condition:IsEncrypted';
+
+ /**
+ * Specifies the Condition:IsMeetingRequest field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_MEETING_REQUEST = 'Condition:IsMeetingRequest';
+
+ /**
+ * Specifies the Condition:IsMeetingResponse field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_MEETING_RESPONSE = 'Condition:IsMeetingResponse';
+
+ /**
+ * Specifies the Condition:IsNDR field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_NDR = 'Condition:IsNDR';
+
+ /**
+ * Specifies the Condition:IsPermissionControlled field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_PERMISSION_CONTROLLED = 'Condition:IsPermissionControlled';
+
+ /**
+ * Specifies the Condition:IsReadReceipt field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_READ_RECEIPT = 'Condition:IsReadReceipt';
+
+ /**
+ * Specifies the Condition:IsSigned field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_SIGNED = 'Condition:IsSigned';
+
+ /**
+ * Specifies the Condition:IsVoicemail field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_IS_VOICEMAIL = 'Condition:IsVoicemail';
+
+ /**
+ * Specifies the Condition:ItemClasses field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_ITEM_CLASSES = 'Condition:ItemClasses';
+
+ /**
+ * Specifies the Condition:MessageClassifications field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_MESSAGE_CLASSIFICATIONS = 'Condition:MessageClassifications';
+
+ /**
+ * Specifies the Condition:NotSentToMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_NOT_SENT_TO_ME = 'Condition:NotSentToMe';
+
+ /**
+ * Specifies the Condition:Sensitivity field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_SENSITIVITY = 'Condition:Sensitivity';
+
+ /**
+ * Specifies the Condition:SentCcMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_SENT_CC_ME = 'Condition:SentCcMe';
+
+ /**
+ * Specifies the Condition:SentOnlyToMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_SENT_ONLY_TO_ME = 'Condition:SentOnlyToMe';
+
+ /**
+ * Specifies the Condition:SentToAddresses field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_SENT_TO_ADDRESSES = 'Condition:SentToAddresses';
+
+ /**
+ * Specifies the Condition:SentToMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_SENT_TO_ME = 'Condition:SentToMe';
+
+ /**
+ * Specifies the Condition:SentToOrCcMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_SENT_TO_OR_CC_ME = 'Condition:SentToOrCcMe';
+
+ /**
+ * Specifies the Condition:WithinDateRange field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_WITHIN_DATE_RANGE = 'Condition:WithinDateRange';
+
+ /**
+ * Specifies the Condition:WithinSizeRange field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITION_WITHIN_SIZE_RANGE = 'Condition:WithinSizeRange';
+
+ /**
+ * Specifies the Conditions field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONDITIONS = 'Conditions';
+
+ /**
+ * Specifies the DisplayName field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DISPLAY_NAME = 'DisplayName';
+
+ /**
+ * Specifies the Exception:Categories field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_CATEGORIES = 'Exception:Categories';
+
+ /**
+ * Specifies the Exception:ContainsBodyStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_CONTAINS_BODY_STRINGS = 'Exception:ContainsBodyStrings';
+
+ /**
+ * Specifies the Exception:ContainsHeaderStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_CONTAINS_HEADER_STRINGS = 'Exception:ContainsHeaderStrings';
+
+ /**
+ * Specifies the Exception:ContainsRecipientStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_CONTAINS_RECIPIENT_STRINGS = 'Exception:ContainsRecipientStrings';
+
+ /**
+ * Specifies the Exception:ContainsSenderStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_CONTAINS_SENDER_STRINGS = 'Exception:ContainsSenderStrings';
+
+ /**
+ * Specifies the Exception:ContainsSubjectOrBodyStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_CONTAINS_SUBJECT_OR_BODY_STRINGS = 'Exception:ContainsSubjectOrBodyStrings';
+
+ /**
+ * Specifies the Exception:ContainsSubjectStrings field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_CONTAINS_SUBJECT_STRINGS = 'Exception:ContainsSubjectStrings';
+
+ /**
+ * Specifies the Exception:FlaggedForAction field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_FLAGGED_FOR_ACTION = 'Exception:FlaggedForAction';
+
+ /**
+ * Specifies the Exception:FromAddresses field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_FROM_ADDRESSES = 'Exception:FromAddresses';
+
+ /**
+ * Specifies the Exception:FromConnectedAccounts field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_FROM_CONNECTED_ACCOUNTS = 'Exception:FromConnectedAccounts';
+
+ /**
+ * Specifies the Exception:HasAttachments field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_HAS_ATTACHMENTS = 'Exception:HasAttachments';
+
+ /**
+ * Specifies the Exception:Importance field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IMPORTANCE = 'Exception:Importance';
+
+ /**
+ * Specifies the Exception:IsApprovalRequest field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_APPROVAL_REQUEST = 'Exception:IsApprovalRequest';
+
+ /**
+ * Specifies the Exception:IsAutomaticForward field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_AUTOMATIC_FORWARD = 'Exception:IsAutomaticForward';
+
+ /**
+ * Specifies the Exception:IsAutomaticReply field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_AUTOMATIC_REPLY = 'Exception:IsAutomaticReply';
+
+ /**
+ * Specifies the Exception:IsEncrypted field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_ENCRYPTED = 'Exception:IsEncrypted';
+
+ /**
+ * Specifies the Exception:IsMeetingRequest field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_MEETING_REQUEST = 'Exception:IsMeetingRequest';
+
+ /**
+ * Specifies the Exception:IsMeetingResponse field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_MEETING_RESPONSE = 'Exception:IsMeetingResponse';
+
+ /**
+ * Specifies the Exception:IsNDR field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_NDR = 'Exception:IsNDR';
+
+ /**
+ * Specifies the Exception:IsPermissionControlled field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_PERMISSION_CONTROLLED = 'Exception:IsPermissionControlled';
+
+ /**
+ * Specifies the Exception:IsReadReceipt field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_READ_RECEIPT = 'Exception:IsReadReceipt';
+
+ /**
+ * Specifies the Exception:IsSigned field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_SIGNED = 'Exception:IsSigned';
+
+ /**
+ * Specifies the Exception:IsVoicemail field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_IS_VOICEMAIL = 'Exception:IsVoicemail';
+
+ /**
+ * Specifies the Exception:ItemClasses field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_ITEM_CLASSES = 'Exception:ItemClasses';
+
+ /**
+ * Specifies the Exception:MessageClassifications field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_MESSAGE_CLASSIFICATIONS = 'Exception:MessageClassifications';
+
+ /**
+ * Specifies the Exception:NotSentToMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_NOT_SENT_TO_ME = 'Exception:NotSentToMe';
+
+ /**
+ * Specifies the Exception:Sensitivity field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_SENSITIVITY = 'Exception:Sensitivity';
+
+ /**
+ * Specifies the Exception:SentCcMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_SENT_CC_ME = 'Exception:SentCcMe';
+
+ /**
+ * Specifies the Exception:SentOnlyToMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_SENT_ONLY_TO_ME = 'Exception:SentOnlyToMe';
+
+ /**
+ * Specifies the Exception:SentToAddresses field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_SENT_TO_ADDRESSES = 'Exception:SentToAddresses';
+
+ /**
+ * Specifies the Exception:SentToMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_SENT_TO_ME = 'Exception:SentToMe';
+
+ /**
+ * Specifies the Exception:SentToOrCcMe field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_SENT_TO_OR_CC_ME = 'Exception:SentToOrCcMe';
+
+ /**
+ * Specifies the Exception:WithinDateRange field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_WITHIN_DATE_RANGE = 'Exception:WithinDateRange';
+
+ /**
+ * Specifies the Exception:WithinSizeRange field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTION_WITHIN_SIZE_RANGE = 'Exception:WithinSizeRange';
+
+ /**
+ * Specifies the Exceptions field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EXCEPTIONS = 'Exceptions';
+
+ /**
+ * Specifies the IsEnabled field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const IS_ENABLED = 'IsEnabled';
+
+ /**
+ * Specifies the IsInError field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const IS_IN_ERROR = 'IsInError';
+
+ /**
+ * Specifies the IsNotSupported field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const IS_NOT_SUPPORTED = 'IsNotSupported';
+
+ /**
+ * Specifies the Priority field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PRIORITY = 'Priority';
+
+ /**
+ * Specifies the RuleId field.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RULE_ID = 'RuleId';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleValidationErrorCodeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleValidationErrorCodeType.php
new file mode 100644
index 00000000..3b602884
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/RuleValidationErrorCodeType.php
@@ -0,0 +1,233 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\RuleValidationErrorCodeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents a rule validation error code that describes what failed validation
+ * for each rule predicate or action.
+ *
+ * @package php-ews\Enumeration
+ */
+class RuleValidationErrorCodeType extends Enumeration
+{
+ /**
+ * Indicates an Active Directory operation failure.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const AD_OPERATION_FAILURE = 'ADOperationFailure';
+
+ /**
+ * Indicates a connected account could not be found.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONNECTED_ACCOUNT_NOT_FOUND = 'ConnectedAccountNotFound';
+
+ /**
+ * Indicates an error creating a rule with an id.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CREATE_WITH_RULE_ID = 'CreateWithRuleId';
+
+ /**
+ * Indicates an error duplicating an operation on the same rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DUPLICATED_OPERATION_ON_THE_SAME_RULE = 'DuplicatedOperationOnTheSameRule';
+
+ /**
+ * Indicates an error with a duplicated priority.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DUPLICATED_PRIORITY = 'DuplicatedPriority';
+
+ /**
+ * Indicates an empty value.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const EMPTY_VALUE_FOUND = 'EmptyValueFound';
+
+ /**
+ * Indicates that a folder does not exist.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FOLDER_DOES_NOT_EXIST = 'FolderDoesNotExist';
+
+ /**
+ * Indicates an invalid address.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_ADDRESS = 'InvalidAddress';
+
+ /**
+ * Indicates an invalid date range
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_DATE_RANGE = 'InvalidDateRange';
+
+ /**
+ * Indicates an invalid folder id.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_FOLDER_ID = 'InvalidFolderId';
+
+ /**
+ * Indicates an invalid size range
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_SIZE_RANGE = 'InvalidSizeRange';
+
+ /**
+ * Indicates an invalid value.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INVALID_VALUE = 'InvalidValue';
+
+ /**
+ * Indicates that a message classification could not be found.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MESSAGE_CLASSIFICATION_NOT_FOUND = 'MessageClassificationNotFound';
+
+ /**
+ * Indicates an action is missing.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MISSING_ACTION = 'MissingAction';
+
+ /**
+ * Indicates a missing parameter.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MISSING_PARAMETER = 'MissingParameter';
+
+ /**
+ * Indicates an error MissingRangeValue.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MISSING_RANGE_VALUE = 'MissingRangeValue';
+
+ /**
+ * Indicates a field is not settable.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NOT_SETTABLE = 'NotSettable';
+
+ /**
+ * Indicates that a recipient does not exist.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RECIPIENT_DOES_NOT_EXIST = 'RecipientDoesNotExist';
+
+ /**
+ * Indicates that a rule could not be found.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const RULE_NOT_FOUND = 'RuleNotFound';
+
+ /**
+ * Indicates that a size less than zero was specified.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SIZE_LESS_THAN_ZERO = 'SizeLessThanZero';
+
+ /**
+ * Indicates that a strings value is too large.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const STRING_VALUE_TOO_BIG = 'StringValueTooBig';
+
+ /**
+ * Indicates an unknown error.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNEXPECTED_ERROR = 'UnexpectedError';
+
+ /**
+ * Indicates an unsupported address.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNSUPPORTED_ADDRESS = 'UnsupportedAddress';
+
+ /**
+ * Indicates an unsupported rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNSUPPORTED_RULE = 'UnsupportedRule';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Scope.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Scope.php
new file mode 100644
index 00000000..bdd082cf
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/Scope.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\Scope.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the scope of a message tracking report.
+ *
+ * @package php-ews\Enumeration
+ */
+class Scope extends Enumeration
+{
+ /**
+ * The message tracking scopes spans across a forest.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FOREST = 'Forest';
+
+ /**
+ * The message tracking scopes spans across an organization.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ORGANIZATION = 'Organization';
+
+ /**
+ * The message tracking scopes spans across a site.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const SITE = 'Site';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchFolderTraversalType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchFolderTraversalType.php
new file mode 100644
index 00000000..89a6fdbb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchFolderTraversalType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SearchFolderTraversalType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of traversal to use for a folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class SearchFolderTraversalType extends Enumeration
+{
+ /**
+ * Consider both direct children as well as all children contained within
+ * those children as well as the children's children, etc.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DEEP = 'Deep';
+
+ /**
+ * Consider only direct children of the parent in question.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const SHALLOW = 'Shallow';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchItemKindType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchItemKindType.php
new file mode 100644
index 00000000..776abce9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchItemKindType.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SearchItemKindType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of item to search for.
+ *
+ * @package php-ews\Enumeration
+ */
+class SearchItemKindType extends Enumeration
+{
+ /**
+ * Indicates that contacts are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONTACT = 'Contacts';
+
+ /**
+ * Indicates that documents are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const DOCUMENT = 'Docs';
+
+ /**
+ * Indicates that email messages are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const EMAIL = 'Email';
+
+ /**
+ * Indicates that faxes are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const FAX = 'Faxes';
+
+ /**
+ * Indicates that instant messages are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const INSTANT_MESSAGE = 'Im';
+
+ /**
+ * Indicates that journals are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const JOURNAL = 'Journals';
+
+ /**
+ * Indicates that meetings are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MEETING = 'Meetings';
+
+ /**
+ * Indicates that notes are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NOTE = 'Notes';
+
+ /**
+ * Indicates that posts are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const POST = 'Posts';
+
+ /**
+ * Indicates that RSS feeds are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const RSS_FEEDS = 'Rssfeeds';
+
+ /**
+ * Indicates that tasks are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TASK = 'Tasks';
+
+ /**
+ * Indicates that voice mails are searched for keywords.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const VOICEMAIL = 'Voicemail';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchPageDirectionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchPageDirectionType.php
new file mode 100644
index 00000000..d5477665
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchPageDirectionType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SearchPageDirectionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the direction for pagination in a search result.
+ *
+ * @package php-ews\Enumeration
+ */
+class SearchPageDirectionType extends Enumeration
+{
+ /**
+ * Move to the next page in the result set.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NEXT = 'Next';
+
+ /**
+ * Move to the previous page in the result set.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PREVIOUS = 'Previous';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchResultType.php
new file mode 100644
index 00000000..aefaeab1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SearchResultType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SearchResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of search to perform.
+ *
+ * @package php-ews\Enumeration
+ */
+class SearchResultType extends Enumeration
+{
+ /**
+ * Return item preview information.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PREVIEW_ONLY = 'PreviewOnly';
+
+ /**
+ * Return the search statistics.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const STATISTICS_ONLY = 'StatisticsOnly';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SensitivityChoicesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SensitivityChoicesType.php
new file mode 100644
index 00000000..86002c85
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SensitivityChoicesType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SensitivityChoicesType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Indicates the sensitivity level of an item.
+ *
+ * @package php-ews\Enumeration
+ */
+class SensitivityChoicesType extends Enumeration
+{
+ /**
+ * Indicates that the item is confidential.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONFIDENTIAL = 'Confidential';
+
+ /**
+ * Indicates that the item has a normal sensitivity.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NORMAL = 'Normal';
+
+ /**
+ * Indicates that the item is personal.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PERSONAL = 'Personal';
+
+ /**
+ * Indicates that the item is private.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const PRIVATE_ITEM = 'Private';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ServiceConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ServiceConfigurationType.php
new file mode 100644
index 00000000..a87fc2c9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ServiceConfigurationType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ServiceConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Specifies the requested service configurations by name.
+ *
+ * @package php-ews\Enumeration
+ */
+class ServiceConfigurationType extends Enumeration
+{
+ /**
+ * Identifies the MailTips service configuration.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const MAIL_TIPS = 'MailTips';
+
+ /**
+ * Identifies the Protection Rules service configuration.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PROTECTION_RULES = 'ProtectionRules';
+
+ /**
+ * Identifies the Unified Messaging service configuration.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNIFIED_MESSAGING_CONFIG = 'UnifiedMessagingConfiguration';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SharingDataType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SharingDataType.php
new file mode 100644
index 00000000..c8832e6f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SharingDataType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SharingDataType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes the type of data that is shared by a shared folder.
+ *
+ * @package php-ews\Enumeration
+ */
+class SharingDataType extends Enumeration
+{
+ /**
+ * Indicates that the shared folder contains calendar information.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CALENDAR = 'Calendar';
+
+ /**
+ * Indicates that the shared folder contains contact information.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONTACTS = 'Contacts';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SortDirectionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SortDirectionType.php
new file mode 100644
index 00000000..6591eb74
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SortDirectionType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SortDirectionType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Identifies a sort order direction.
+ *
+ * @package php-ews\Enumeration
+ */
+class SortDirectionType extends Enumeration
+{
+ /**
+ * Items are sorted in ascending order.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ASCENDING = 'Ascending';
+
+ /**
+ * Items are sorted in descending order.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DESCENDING = 'Descending';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/StandardGroupByType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/StandardGroupByType.php
new file mode 100644
index 00000000..01b6d2b6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/StandardGroupByType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\StandardGroupByType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the standard grouping and aggregating mechanisms for a grouped
+ * FindItem operation.
+ *
+ * @package php-ews\Enumeration
+ */
+class StandardGroupByType extends Enumeration
+{
+ /**
+ * Groups by message:ConversationTopic and aggregates on
+ * item:DateTimeReceived (maximum).
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONVERSATION_TOPIC = 'ConversationTopic';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SubscriptionStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SubscriptionStatusType.php
new file mode 100644
index 00000000..2652df6d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SubscriptionStatusType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SubscriptionStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Describes the status of a push subscription.
+ *
+ * @package php-ews\Enumeration
+ */
+class SubscriptionStatusType extends Enumeration
+{
+ /**
+ * Indicates that the notification has been received and the subscription is
+ * to continue.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OK = 'OK';
+
+ /**
+ * Indicates that push notifications from the subscription should be ceased.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const UNSUBSCRIBE = 'Unsubscribe';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SuggestionQuality.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SuggestionQuality.php
new file mode 100644
index 00000000..baff097e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SuggestionQuality.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SuggestionQuality.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the quality of the day for containing quality suggested meeting
+ * times.
+ *
+ * @package php-ews\Enumeration
+ */
+class SuggestionQuality extends Enumeration
+{
+ /**
+ * Indicates that the suggested meeting time is excellent.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const EXCELLENT = 'Excellent';
+
+ /**
+ * Indicates that the suggested meeting time is fair.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FAIR = 'Fair';
+
+ /**
+ * Indicates that the suggested meeting time is good.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const GOOD = 'Good';
+
+ /**
+ * Indicates that the suggested meeting time is poor.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const POOR = 'Poor';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SyncFolderItemsScopeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SyncFolderItemsScopeType.php
new file mode 100644
index 00000000..0ae1f96b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/SyncFolderItemsScopeType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\SyncFolderItemsScopeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines whether just items or items and folder associated information are
+ * returned in a synchronization response.
+ *
+ * @package php-ews\Enumeration
+ */
+class SyncFolderItemsScopeType extends Enumeration
+{
+ /**
+ * Specifies that only items in the folder are returned in a synchronization
+ * response.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NORMAL = 'NormalItems';
+
+ /**
+ * Specifies that both items in the folder and folder associated information
+ * are returned in a synchronization response.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const NORMAL_AND_ASSOCIATED = 'NormalAndAssociatedItems';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskDelegateStateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskDelegateStateType.php
new file mode 100644
index 00000000..c31325b5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskDelegateStateType.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\TaskDelegateStateType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the status of a delegated task.
+ *
+ * @package php-ews\Enumeration
+ */
+class TaskDelegateStateType extends Enumeration
+{
+ /**
+ * Indicates that the delegate has accepted the task.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ACCEPTED = 'Accepted';
+
+ /**
+ * Indicates that the delegate has declined the task.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DECLINED = 'Declined';
+
+ /**
+ * Indicates that the task request is out of bounds.
+ *
+ * This is an internal Outlook value and should not be used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MAX = 'Max';
+
+ /**
+ * Indicates that the task is not delegated or the task request has been
+ * created but not sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NO_MATCH = 'NoMatch';
+
+ /**
+ * Indicates that the task is a new task request that has been sent, but the
+ * delegate has not yet responded.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OWN_NEW = 'OwnNew';
+
+ /**
+ * Indicates that the task is owned.
+ *
+ * This value should not be used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const OWNED = 'Owned';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskStatusType.php
new file mode 100644
index 00000000..5194e998
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TaskStatusType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\TaskStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Represents the status of a task item.
+ *
+ * @package php-ews\Enumeration
+ */
+class TaskStatusType extends Enumeration
+{
+ /**
+ * Indicates that the task has been completed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const COMPLETED = 'Completed';
+
+ /**
+ * Indicates that the task has been deferred.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const DEFERRED = 'Deferred';
+
+ /**
+ * Indicates that the task has been started.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const IN_PROGRESS = 'InProgress';
+
+ /**
+ * Indicates that the task has not yet been started.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const NOT_STARTED = 'NotStarted';
+
+ /**
+ * Indicates that the task is waiting on others.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const WAITING_ON_OTHERS = 'WaitingOnOthers';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TransitionTargetKindType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TransitionTargetKindType.php
new file mode 100644
index 00000000..2cf0ddbb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/TransitionTargetKindType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\TransitionTargetKindType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the kind of a transition.
+ *
+ * @package php-ews\Enumeration
+ */
+class TransitionTargetKindType extends Enumeration
+{
+ /**
+ * Specifies that the time zone transition target is a group of time zone
+ * transitions.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const GROUP = 'Group';
+
+ /**
+ * Specifies that the time zone transition target is a time zone period.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const PERIOD = 'Period';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UnindexedFieldURIType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UnindexedFieldURIType.php
new file mode 100644
index 00000000..182261b8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UnindexedFieldURIType.php
@@ -0,0 +1,2941 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\UnindexedFieldURIType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines frequently referenced properties by URI.
+ *
+ * @package php-ews\Enumeration
+ */
+class UnindexedFieldURIType extends Enumeration
+{
+ /**
+ * Identifies the AdjacentMeetingCount property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_ADJACENT_MEETING_COUNT = 'calendar:AdjacentMeetingCount';
+
+ /**
+ * Identifies the AdjacentMeetings property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_ADJACENT_MEETINGS = 'calendar:AdjacentMeetings';
+
+ /**
+ * Identifies the AllowNewTimeProposal property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_ALLOW_NEW_TIME_PROPOSAL = 'calendar:AllowNewTimeProposal';
+
+ /**
+ * Identifies the AppointmentReplyTime property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_APPOINTMENT_REPLY_TIME = 'calendar:AppointmentReplyTime';
+
+ /**
+ * Identifies the AppointmentSequenceNumber property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_APPOINTMENT_SEQUENCE_NUMBER = 'calendar:AppointmentSequenceNumber';
+
+ /**
+ * Identifies the AppointmentState property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_APPOINTMENT_STATE = 'calendar:AppointmentState';
+
+ /**
+ * Identifies the ConferenceType property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_CONFERENCE_TYPE = 'calendar:ConferenceType';
+
+ /**
+ * Identifies the ConflictingMeetingCount property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_CONFLICTING_MEETING_COUNT = 'calendar:ConflictingMeetingCount';
+
+ /**
+ * Identifies the ConflictingMeetings property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_CONFLICTING_MEETINGS = 'calendar:ConflictingMeetings';
+
+ /**
+ * Identifies the DateTimeStamp property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CALENDAR_DATE_TIME_STAMP = 'calendar:DateTimeStamp';
+
+ /**
+ * Identifies the DeletedOccurrences property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_DELETED_OCCURRENCES = 'calendar:DeletedOccurrences';
+
+ /**
+ * Identifies the Duration property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_DURATION = 'calendar:Duration';
+
+ /**
+ * Identifies the End property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_END = 'calendar:End';
+
+ /**
+ * Identifies the EndTimeZone property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CALENDAR_END_TIMEZONE = 'calendar:EndTimeZone';
+
+ /**
+ * Identifies the EndTimeZoneId property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR_END_TIME_ZONE_ID = 'calendar:EndTimeZoneId';
+
+ /**
+ * Identifies the EndWallClock property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR_END_WALL_CLOCK = 'calendar:EndWallClock';
+
+ /**
+ * Identifies the FirstOccurrence property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_FIRST_OCCURRENCE = 'calendar:FirstOccurrence';
+
+ /**
+ * Identifies the IsAllDayEvent property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_IS_ALL_DAY_EVENT = 'calendar:IsAllDayEvent';
+
+ /**
+ * Identifies the IsCancelled property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_IS_CANCELLED = 'calendar:IsCancelled';
+
+ /**
+ * Identifies the IsMeeting property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_IS_MEETING = 'calendar:IsMeeting';
+
+ /**
+ * Identifies the IsOnlineMeeting property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_IS_ONLINE_MEETING = 'calendar:IsOnlineMeeting';
+
+ /**
+ * Identifies the IsOrganizer property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR_IS_ORGANIZER = 'calendar:IsOrganizer';
+
+ /**
+ * Identifies the IsRecurring property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_IS_RECURRING = 'calendar:IsRecurring';
+
+ /**
+ * Identifies the IsResponseRequested property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_IS_RESPONSE_REQUESTED = 'calendar:IsResponseRequested';
+
+ /**
+ * Identifies the CalendarItemType property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_ITEM_TYPE = 'calendar:CalendarItemType';
+
+ /**
+ * Identifies the JoinOnlineMeetingUrl property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR_JOIN_ONLINE_MEETING_URL = 'calendar:JoinOnlineMeetingUrl';
+
+ /**
+ * Identifies the LastOccurrence property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_LAST_OCCURRENCE = 'calendar:LastOccurrence';
+
+ /**
+ * Identifies the LegacyFreeBusyStatus property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_LEGACY_FREE_BUSY_STATUS = 'calendar:LegacyFreeBusyStatus';
+
+ /**
+ * Identifies the Location property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_LOCATION = 'calendar:Location';
+
+ /**
+ * Identifies the MeetingRequestWasSent property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_MEETING_REQUEST_WAS_SENT = 'calendar:MeetingRequestWasSent';
+
+ /**
+ * Identifies the MeetingTimeZone property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_MEETING_TIMEZONE = 'calendar:MeetingTimeZone';
+
+ /**
+ * Identifies the MeetingWorkspaceUrl property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_MEETING_WORKSPACE_URL = 'calendar:MeetingWorkspaceUrl';
+
+ /**
+ * Identifies the ModifiedOccurrences property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_MODIFIED_OCCURRENCES = 'calendar:ModifiedOccurrences';
+
+ /**
+ * Identifies the MyResponseType property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_MY_RESPONSE_TYPE = 'calendar:MyResponseType';
+
+ /**
+ * Identifies the NetShowUrl property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_NET_SHOW_URL = 'calendar:NetShowUrl';
+
+ /**
+ * Identifies the OnlineMeetingSettings property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR_ONLINE_MEETING_SETTINGS = 'calendar:OnlineMeetingSettings';
+
+ /**
+ * Identifies the OptionalAttendees property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_OPTIONAL_ATTENDEES = 'calendar:OptionalAttendees';
+
+ /**
+ * Identifies the Organizer property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_ORGANIZER = 'calendar:Organizer';
+
+ /**
+ * Identifies the OriginalStart property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_ORIGINAL_START = 'calendar:OriginalStart';
+
+ /**
+ * Identifies the Recurrence property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_RECURRENCE = 'calendar:Recurrence';
+
+ /**
+ * Identifies the RecurrenceId property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CALENDAR_RECURRENCE_ID = 'calendar:RecurrenceId';
+
+ /**
+ * Identifies the RequiredAttendees property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_REQUIRED_ATTENDEES = 'calendar:RequiredAttendees';
+
+ /**
+ * Identifies the Resources property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_RESOURCES = 'calendar:Resources';
+
+ /**
+ * Identifies the Start property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_START = 'calendar:Start';
+
+ /**
+ * Identifies the StartTimeZone property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CALENDAR_START_TIMEZONE = 'calendar:StartTimeZone';
+
+ /**
+ * Identifies the StartTimeZoneId property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR_START_TIME_ZONE_ID = 'calendar:StartTimeZoneId';
+
+ /**
+ * Identifies the StartWallClock property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CALENDAR_START_WALL_CLOCK = 'calendar:StartWallClock';
+
+ /**
+ * Identifies the TimeZone property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_TIMEZONE = 'calendar:TimeZone';
+
+ /**
+ * Identifies the UID property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CALENDAR_UID = 'calendar:UID';
+
+ /**
+ * Identifies the When property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CALENDAR_WHEN = 'calendar:When';
+
+ /**
+ * Identifies the Alias property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_ALIAS = 'contacts:Alias';
+
+ /**
+ * Identifies the AssistantName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_ASSISTANT_NAME = 'contacts:AssistantName';
+
+ /**
+ * Identifies the Birthday property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_BIRTHDAY = 'contacts:Birthday';
+
+ /**
+ * Identifies the BusinessHomePage property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_BUSINESS_HOME_PAGE = 'contacts:BusinessHomePage';
+
+ /**
+ * Identifies the Children property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_CHILDREN = 'contacts:Children';
+
+ /**
+ * Identifies the Companies property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_COMPANIES = 'contacts:Companies';
+
+ /**
+ * Identifies the CompanyName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_COMPANY_NAME = 'contacts:CompanyName';
+
+ /**
+ * Identifies the CompleteName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_COMPLETE_NAME = 'contacts:CompleteName';
+
+ /**
+ * Identifies the Culture property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_CULTURE = 'contacts:Culture';
+
+ /**
+ * Identifies the Department property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_DEPARTMENT = 'contacts:Department';
+
+ /**
+ * Identifies the DirectReports property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_DIRECT_REPORTS = 'contacts:DirectReports';
+
+ /**
+ * Identifies the DirectoryId property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_DIRECTORY_ID = 'contacts:DirectoryId';
+
+ /**
+ * Identifies the DisplayName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_DISPLAY_NAME = 'contacts:DisplayName';
+
+ /**
+ * Identifies the EmailAddresses property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_EMAIL_ADDRESSES = 'contacts:EmailAddresses';
+
+ /**
+ * Identifies the FileAs property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_FILE_AS = 'contacts:FileAs';
+
+ /**
+ * Identifies the FileAsMapping property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_FILE_AS_MAPPING = 'contacts:FileAsMapping';
+
+ /**
+ * Identifies the Generation property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_GENERATION = 'contacts:Generation';
+
+ /**
+ * Identifies the GivenName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_GIVEN_NAME = 'contacts:GivenName';
+
+ /**
+ * Identifies the HasPicture property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONTACTS_HAS_PICTURE = 'contacts:HasPicture';
+
+ /**
+ * Identifies the ImAddresses property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_IM_ADDRESSES = 'contacts:ImAddresses';
+
+ /**
+ * Identifies the Initials property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_INITIALS = 'contacts:Initials';
+
+ /**
+ * Identifies the JobTitle property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_JOB_TITLE = 'contacts:JobTitle';
+
+ /**
+ * Identifies the Manager property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_MANAGER = 'contacts:Manager';
+
+ /**
+ * Identifies the ManagerMailbox property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_MANAGER_MAILBOX = 'contacts:ManagerMailbox';
+
+ /**
+ * Identifies the MiddleName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_MIDDLE_NAME = 'contacts:MiddleName';
+
+ /**
+ * Identifies the Mileage property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_MILEAGE = 'contacts:Mileage';
+
+ /**
+ * Identifies the MSExchangeCertificate property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_MS_EXCHANGE_CERTIFICATE = 'contacts:MSExchangeCertificate';
+
+ /**
+ * Identifies the Nickname property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_NICKNAME = 'contacts:Nickname';
+
+ /**
+ * Identifies the Notes property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_NOTES = 'contacts:Notes';
+
+ /**
+ * Identifies the OfficeLocation property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_OFFICE_LOCATION = 'contacts:OfficeLocation';
+
+ /**
+ * Identifies the PhoneNumbers property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHONE_NUMBERS = 'contacts:PhoneNumbers';
+
+ /**
+ * Identifies the PhoneticFirstName property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_PHONETIC_FIRST_NAME = 'contacts:PhoneticFirstName';
+
+ /**
+ * Identifies the PhoneticFullName property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_PHONETIC_FULL_NAME = 'contacts:PhoneticFullName';
+
+ /**
+ * Identifies the PhoneticLastName property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_PHONETIC_LAST_NAME = 'contacts:PhoneticLastName';
+
+ /**
+ * Identifies the Photo property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_PHOTO = 'contacts:Photo';
+
+ /**
+ * Identifies the PhysicalAddresses property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PHYSICAL_ADDRESSES = 'contacts:PhysicalAddresses';
+
+ /**
+ * Identifies the PostalAddressIndex property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_POSTAL_ADDRESS_INDEX = 'contacts:PostalAddressIndex';
+
+ /**
+ * Identifies the Profession property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_PROFESSION = 'contacts:Profession';
+
+ /**
+ * Identifies the ContactSource property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_SOURCE = 'contacts:ContactSource';
+
+ /**
+ * Identifies the SpouseName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_SPOUSE_NAME = 'contacts:SpouseName';
+
+ /**
+ * Identifies the Surname property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_SURNAME = 'contacts:Surname';
+
+ /**
+ * Identifies the UserSMIMECertificate property.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ const CONTACTS_USER_SMIME_CERTIFICATE = 'contacts:UserSMIMECertificate';
+
+ /**
+ * Identifies the WeddingAnniversary property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const CONTACTS_WEDDING_ANNIVERSARY = 'contacts:WeddingAnniversary';
+
+ /**
+ * Identifies the Categories property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_CATEGORIES = 'conversation:Categories';
+
+ /**
+ * Identifies the FlagStatus property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_FLAG_STATUS = 'conversation:FlagStatus';
+
+ /**
+ * Identifies the GlobalCategories property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_CATEGORIES = 'conversation:GlobalCategories';
+
+ /**
+ * Identifies the GlobalFlagStatus property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_FLAG_STATUS = 'conversation:GlobalFlagStatus';
+
+ /**
+ * Identifies the GlobalHasAttachments property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_HAS_ATTACHMENTS = 'conversation:GlobalHasAttachments';
+
+ /**
+ * Identifies the GlobalImportance property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_IMPORTANCE = 'conversation:GlobalImportance';
+
+ /**
+ * Identifies the GlobalItemClasses property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_ITEM_CLASSES = 'conversation:GlobalItemClasses';
+
+ /**
+ * Identifies the GlobalItemIds property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_ITEM_IDS = 'conversation:GlobalItemIds';
+
+ /**
+ * Identifies the GlobalLastDeliveryTime property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_LAST_DELIVERY_TIME = 'conversation:GlobalLastDeliveryTime';
+
+ /**
+ * Identifies the GlobalMessageCount property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_MESSAGE_COUNT = 'conversation:GlobalMessageCount';
+
+ /**
+ * Identifies the GlobalParentFolderId property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_PARENT_FOLDER_ID = 'conversation:GlobalParentFolderId';
+
+ /**
+ * Identifies the GlobalSize property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_SIZE = 'conversation:GlobalSize';
+
+ /**
+ * Identifies the GlobalUniqueRecipients property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_UNIQUE_RECIPIENTS = 'conversation:GlobalUniqueRecipients';
+
+ /**
+ * Identifies the GlobalUniqueSenders property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_UNIQUE_SENDERS = 'conversation:GlobalUniqueSenders';
+
+ /**
+ * Identifies the GlobalUniqueUnreadSenders property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_UNIQUE_UNREAD_SENDERS = 'conversation:GlobalUniqueUnreadSenders';
+
+ /**
+ * Identifies the GlobalUnreadCount property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_GLOBAL_UNREAD_COUNT = 'conversation:GlobalUnreadCount';
+
+ /**
+ * Identifies the GroupingAction property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_GROUPING_ACTION = 'conversation:GroupingAction';
+
+ /**
+ * Identifies the HasAttachments property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_HAS_ATTACHMENTS = 'conversation:HasAttachments';
+
+ /**
+ * Identifies the ConversationId property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_ID = 'conversation:ConversationId';
+
+ /**
+ * Identifies the Importance property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_IMPORTANCE = 'conversation:Importance';
+
+ /**
+ * Identifies the InstanceKey property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_INSTANCE_KEY = 'conversation:InstanceKey';
+
+ /**
+ * Identifies the ItemClasses property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_ITEM_CLASSES = 'conversation:ItemClasses';
+
+ /**
+ * Identifies the ItemIds property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_ITEM_IDS = 'conversation:ItemIds';
+
+ /**
+ * Identifies the LastDeliveryTime property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_LAST_DELIVERY_TIME = 'conversation:LastDeliveryTime';
+
+ /**
+ * Identifies the LastModifiedTime property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_LAST_MODIFIED_TIME = 'conversation:LastModifiedTime';
+
+ /**
+ * Identifies the MessageCount property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_MESSAGE_COUNT = 'conversation:MessageCount';
+
+ /**
+ * Identifies the NextPredictedAction property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_NEXT_PREDICTED_ACTION = 'conversation:NextPredictedAction';
+
+ /**
+ * Identifies the Preview property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CONVERSATION_PREVIEW = 'conversation:Preview';
+
+ /**
+ * Identifies the Size property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_SIZE = 'conversation:Size';
+
+ /**
+ * Identifies the ConversationTopic property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_TOPIC = 'conversation:ConversationTopic';
+
+ /**
+ * Identifies the UniqueRecipients property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_UNIQUE_RECIPIENTS = 'conversation:UniqueRecipients';
+
+ /**
+ * Identifies the UniqueSenders property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_UNIQUE_SENDERS = 'conversation:UniqueSenders';
+
+ /**
+ * Identifies the UniqueUnreadSenders property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_UNIQUE_UNREAD_SENDERS = 'conversation:UniqueUnreadSenders';
+
+ /**
+ * Identifies the UnreadCount property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const CONVERSATION_UNREAD_COUNT = 'conversation:UnreadCount';
+
+ /**
+ * Identifies the Members property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DISTRIBUTION_LIST_MEMBERS = 'distributionlist:Members';
+
+ /**
+ * Identifies the ChildFolderCount property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_CHILD_FOLDER_COUNT = 'folder:ChildFolderCount';
+
+ /**
+ * Identifies the DisplayName property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_DISPLAY_NAME = 'folder:DisplayName';
+
+ /**
+ * Identifies the EffectiveRights property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FOLDER_EFFECTIVE_RIGHTS = 'folder:EffectiveRights';
+
+ /**
+ * Identifies the FolderClass property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_FOLDER_CLASS = 'folder:FolderClass';
+
+ /**
+ * Identifies the FolderId property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_FOLDER_ID = 'folder:FolderId';
+
+ /**
+ * Identifies the ManagedFolderInformation property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_MANAGED_FOLDER_INFORMATION = 'folder:ManagedFolderInformation';
+
+ /**
+ * Identifies the ParentFolderId property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_PARENT_FOLDER_ID = 'folder:ParentFolderId';
+
+ /**
+ * Identifies the PermissionSet property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FOLDER_PERMISSION_SET = 'folder:PermissionSet';
+
+ /**
+ * Identifies the SearchParameters property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_SEARCH_PARAMETERS = 'folder:SearchParameters';
+
+ /**
+ * Identifies the SharingEffectiveRights property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const FOLDER_SHARING_EFFECTIVE_RIGHTS = 'folder:SharingEffectiveRights';
+
+ /**
+ * Identifies the TotalCount property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_TOTAL_COUNT = 'folder:TotalCount';
+
+ /**
+ * Identifies the UnreadCount property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const FOLDER_UNREAD_COUNT = 'folder:UnreadCount';
+
+ /**
+ * Identifies the ArchiveTag property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_ARCHIVE_TAG = 'item:ArchiveTag';
+
+ /**
+ * Identifies the Attachments property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_ATTACHMENTS = 'item:Attachments';
+
+ /**
+ * Identifies the BlockStatus property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_BLOCK_STATUS = 'item:BlockStatus';
+
+ /**
+ * Identifies the Body property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_BODY = 'item:Body';
+
+ /**
+ * Identifies the Categories property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_CATEGORIES = 'item:Categories';
+
+ /**
+ * Identifies the ItemClass property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_CLASS = 'item:ItemClass';
+
+ /**
+ * Identifies the ConversationId property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_CONVERSATION_ID = 'item:ConversationId';
+
+ /**
+ * Identifies the Culture property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_CULTURE = 'item:Culture';
+
+ /**
+ * Identifies the DateTimeCreated property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_DATE_TIME_CREATED = 'item:DateTimeCreated';
+
+ /**
+ * Identifies the DateTimeReceived property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_DATE_TIME_RECEIVED = 'item:DateTimeReceived';
+
+ /**
+ * Identifies the DateTimeSent property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_DATE_TIME_SENT = 'item:DateTimeSent';
+
+ /**
+ * Identifies the DisplayCc property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_DISPLAY_CC = 'item:DisplayCc';
+
+ /**
+ * Identifies the DisplayTo property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_DISPLAY_TO = 'item:DisplayTo';
+
+ /**
+ * Identifies the EffectiveRights property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_EFFECTIVE_RIGHTS = 'item:EffectiveRights';
+
+ /**
+ * Identifies the EntityExtractionResult property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_ENTITY_EXTRACTION_RESULT = 'item:EntityExtractionResult';
+
+ /**
+ * Identifies the Flag property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_FLAG = 'item:Flag';
+
+ /**
+ * Identifies the GroupingAction property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_GROUPING_ACTION = 'item:GroupingAction';
+
+ /**
+ * Identifies the HasAttachments property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_HAS_ATTACHMENTS = 'item:HasAttachments';
+
+ /**
+ * Identifies the HasBlockedImages property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_HAS_BLOCKED_IMAGES = 'item:HasBlockedImages';
+
+ /**
+ * Identifies the ItemId property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_ID = 'item:ItemId';
+
+ /**
+ * Identifies the Importance property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_IMPORTANCE = 'item:Importance';
+
+ /**
+ * Identifies the InReplyTo property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_IN_REPLY_TO = 'item:InReplyTo';
+
+ /**
+ * Identifies the InstanceKey property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_INSTANCE_KEY = 'item:InstanceKey';
+
+ /**
+ * Identifies the InternetMessageHeaders property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_INTERNET_MESSAGE_HEADERS = 'item:InternetMessageHeaders';
+
+ /**
+ * Identifies the IsAssociated property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_IS_ASSOCIATED = 'item:IsAssociated';
+
+ /**
+ * Identifies the IsAssociated property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_IS_DRAFT = 'item:IsDraft';
+
+ /**
+ * Identifies the IsFromMe property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_IS_FROM_ME = 'item:IsFromMe';
+
+ /**
+ * Identifies the IsResend property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_IS_RESEND = 'item:IsResend';
+
+ /**
+ * Identifies the IsSubmitted property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_IS_SUBMITTED = 'item:IsSubmitted';
+
+ /**
+ * Identifies the IsUnmodified property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_IS_UNMODIFIED = 'item:IsUnmodified';
+
+ /**
+ * Identifies the LastModifiedName property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_LAST_MODIFIED_NAME = 'item:LastModifiedName';
+
+ /**
+ * Identifies the LastModifiedTime property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_LAST_MODIFIED_TIME = 'item:LastModifiedTime';
+
+ /**
+ * Identifies the MimeContent property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_MIME_CONTENT = 'item:MimeContent';
+
+ /**
+ * Identifies the NextPredictedAction property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_NEXT_PREDICTED_ACTION = 'item:NextPredictedAction';
+
+ /**
+ * Identifies the NormalizedBody property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_NORMALIZED_BODY = 'item:NormalizedBody';
+
+ /**
+ * Identifies the ParentFolderId property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_PARENT_FOLDER_ID = 'item:ParentFolderId';
+
+ /**
+ * Identifies the PolicyTag property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_POLICY_TAG = 'itemPolicyTag';
+
+ /**
+ * Identifies the Preview property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_PREVIEW = 'item:Preview';
+
+ /**
+ * Identifies the ReminderDueBy property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_REMINDER_DUE_BY = 'item:ReminderDueBy';
+
+ /**
+ * Identifies the ReminderIsSet property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_REMINDER_IS_SET = 'item:ReminderIsSet';
+
+ /**
+ * Identifies the ReminderMinutesBeforeStart property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_REMINDER_MINUTES_BEFORE_START = 'item:ReminderMinutesBeforeStart';
+
+ /**
+ * Identifies the ReminderNextTime property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_REMINDER_NEXT_TIME = 'item:ReminderNextTime';
+
+ /**
+ * Identifies the ResponseObjects property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_RESPONSE_OBJECTS = 'item:ResponseObjects';
+
+ /**
+ * Identifies the RetentionDate property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_RETENTION_DATE = 'item:RetentionDate';
+
+ /**
+ * Identifies the RightsManagementLicenseData property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_RIGHTS_MANAGEMENT_LICENSE_DATA = 'item:RightsManagementLicenseData';
+
+ /**
+ * Identifies the Sensitivity property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_SENSITIVITY = 'item:Sensitivity';
+
+ /**
+ * Identifies the Size property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_SIZE = 'item:Size';
+
+ /**
+ * Identifies the StoreEntryId property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_STORE_ENTRY_ID = 'item:StoreEntryId';
+
+ /**
+ * Identifies the Subject property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const ITEM_SUBJECT = 'item:Subject';
+
+ /**
+ * Identifies the TextBody property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ITEM_TEXT_BODY = 'item:TextBody';
+
+ /**
+ * Identifies the UniqueBody property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_UNIQUE_BODY = 'item:UniqueBody';
+
+ /**
+ * Identifies the WebClientEditFormQueryString property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_WEB_CLIENT_EDIT_FROM_QUERY_STRING = 'item:WebClientEditFormQueryString';
+
+ /**
+ * Identifies the WebClientReadFormQueryString property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ITEM_WEB_CLIENT_READ_FROM_QUERY_STRING = 'item:WebClientReadFormQueryString';
+
+ /**
+ * Identifies the AssociatedCalendarItemId property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_ASSOCIATED_CALENDAR_ITEM_ID = 'meeting:AssociatedCalendarItemId';
+
+ /**
+ * Identifies the IsDelegated property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_IS_DELEGATED = 'meeting:IsDelegated';
+
+ /**
+ * Identifies the IsOutOfDate property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_IS_OUT_OF_DATE = 'meeting:IsOutOfDate';
+
+ /**
+ * Identifies the HasBeenProcessed property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_HAS_BEEN_PROCESSED = 'meeting:HasBeenProcessed';
+
+ /**
+ * Identifies the ProposedEnd property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MEETING_PROPOSED_END = 'meeting:ProposedEnd';
+
+ /**
+ * Identifies the ProposedStart property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MEETING_PROPOSED_START = 'meeting:ProposedStart';
+
+ /**
+ * Identifies the ChangeHighlights property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MEETING_REQUEST_CHANGE_HIGHLIGHTS = 'meetingRequest:ChangeHighlights';
+
+ /**
+ * Identifies the IntendedFreeBusyStatus property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_REQUEST_INTENDED_FREE_BUSY_STATUS = 'meetingRequest:IntendedFreeBusyStatus';
+
+ /**
+ * Identifies the MeetingRequestType property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_REQUEST_TYPE = 'meetingRequest:MeetingRequestType';
+
+ /**
+ * Identifies the ResponseType property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MEETING_RESPONSE_TYPE = 'meeting:ResponseType';
+
+ /**
+ * Identifies the BccRecipients property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_BCC_RECIPIENTS = 'message:BccRecipients';
+
+ /**
+ * Identifies the CcRecipients property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_CC_RECIPIENTS = 'message:CcRecipients';
+
+ /**
+ * Identifies the ConversationIndex property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_CONVERSATION_INDEX = 'message:ConversationIndex';
+
+ /**
+ * Identifies the ConversationTopic property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_CONVERSATION_TOPIC = 'message:ConversationTopic';
+
+ /**
+ * Identifies the From property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_FROM = 'message:From';
+
+ /**
+ * Identifies the InternetMessageId property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_INTERNET_MESSAGE_ID = 'message:InternetMessageId';
+
+ /**
+ * Identifies the IsDeliveryReceiptRequested property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_IS_DELIVERY_RECEIPT_REQUESTED = 'message:IsDeliveryReceiptRequested';
+
+ /**
+ * Identifies the IsRead property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_IS_READ = 'message:IsRead';
+
+ /**
+ * Identifies the IsReadReceiptRequested property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_IS_READ_RECEIPT_REQUESTED = 'message:IsReadReceiptRequested';
+
+ /**
+ * Identifies the IsResponseRequested property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_IS_RESPONSE_REQUESTED = 'message:IsResponseRequested';
+
+ /**
+ * Identifies the ReceivedBy property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MESSAGE_RECEIVED_BY = 'message:ReceivedBy';
+
+ /**
+ * Identifies the ReceivedRepresenting property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const MESSAGE_RECEIVED_REPRESENTING = 'message:ReceivedRepresenting';
+
+ /**
+ * Identifies the References property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_REFERENCES = 'message:References';
+
+ /**
+ * Identifies the ReplyTo property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_REPLY_TO = 'message:ReplyTo';
+
+ /**
+ * Identifies the Sender property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_SENDER = 'message:Sender';
+
+ /**
+ * Identifies the ToRecipients property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const MESSAGE_TO_RECIPIENTS = 'message:ToRecipients';
+
+ /**
+ * Identifies the AssistantNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_ASSISTANT_NAMES = 'persona:AssistantNames';
+
+ /**
+ * Identifies the AssistantPhoneNumbers property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_ASSISTANT_PHONE_NUMBERS = 'persona:AssistantPhoneNumbers';
+
+ /**
+ * Identifies the Attributions property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_ATTRIBUTIONS = 'persona:Attributions';
+
+ /**
+ * Identifies the Birthdays property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_BIRTHDAYS = 'persona:Birthdays';
+
+ /**
+ * Identifies the Bodies property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_BODIES = 'persona:Bodies';
+
+ /**
+ * Identifies the BusinessAddresses property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_BUSINESS_ADDRESSES = 'persona:BusinessAddresses';
+
+ /**
+ * Identifies the BusinessHomePages property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_BUSINESS_HOME_PAGES = 'persona:BusinessHomePages';
+
+ /**
+ * Identifies the BusinessPhoneNumbers property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_BUSINESS_PHONE_NUMBERS = 'persona:BusinessPhoneNumbers';
+
+ /**
+ * Identifies the BusinessPhoneNumbers2 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_BUSINESS_PHONE_NUMBERS_2 = 'persona:BusinessPhoneNumbers2';
+
+ /**
+ * Identifies the CallbackPhones property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_CALLBACK_PHONES = 'persona:CallbackPhones';
+
+ /**
+ * Identifies the CarPhones property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_CAR_PHONES = 'persona:CarPhones';
+
+ /**
+ * Identifies the Children property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_CHILDREN = 'persona:Children';
+
+ /**
+ * Identifies the CompanyName property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_COMPANY_NAME = 'persona:CompanyName';
+
+ /**
+ * Identifies the CompanyNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_COMPANY_NAMES = 'persona:CompanyNames';
+
+ /**
+ * Identifies the CreationTime property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_CREATION_TIME = 'persona:CreationTime';
+
+ /**
+ * Identifies the Departments property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_DEPARTMENTS = 'persona:Departments';
+
+ /**
+ * Identifies the DisplayName property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_DISPLAY_NAME = 'persona:DisplayName';
+
+ /**
+ * Identifies the DisplayNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_DISPLAY_NAMES = 'persona:DisplayNames';
+
+ /**
+ * Identifies the DisplayNamePrefix property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_DISPLAY_NAME_PREFIX = 'persona:DisplayNamePrefix';
+
+ /**
+ * Identifies the DisplayNamePrefixes property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_DISPLAY_NAME_PREFIXES = 'persona:DisplayNamePrefixes';
+
+ /**
+ * Identifies the EmailAddress property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_EMAIL_ADDRESS = 'persona:EmailAddress';
+
+ /**
+ * Identifies the EmailAddresses property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_EMAIL_ADDRESSES = 'persona:EmailAddresses';
+
+ /**
+ * Identifies the Emails1 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_EMAILS_1 = 'persona:Emails1';
+
+ /**
+ * Identifies the Emails2 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_EMAILS_2 = 'persona:Emails2';
+
+ /**
+ * Identifies the Emails3 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_EMAILS_3 = 'persona:Emails3';
+
+ /**
+ * Identifies the ExtendedProperties property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_EXTENDED_PROPERTIES = 'persona:ExtendedProperties';
+
+ /**
+ * Identifies the FileAs property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_FILE_AS = 'persona:FileAs';
+
+ /**
+ * Identifies the FileAsId property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_FILE_AS_ID = 'persona:FileAsId';
+
+ /**
+ * Identifies the FileAsIds property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_FILE_AS_IDS = 'persona:FileAsIds';
+
+ /**
+ * Identifies the FileAses property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_FILE_ASES = 'persona:FileAses';
+
+ /**
+ * Identifies the FolderIds property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_FOLDER_IDS = 'persona:FolderIds';
+
+ /**
+ * Identifies the Generations property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_GENERATIONS = 'persona:Generations';
+
+ /**
+ * Identifies the GivenName property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_GIVEN_NAME = 'persona:GivenName';
+
+ /**
+ * Identifies the GivenNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_GIVEN_NAMES = 'persona:GivenNames';
+
+ /**
+ * Identifies the Hobbies property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_HOBBIES = 'persona:Hobbies';
+
+ /**
+ * Identifies the HomeAddresses property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_HOME_ADDRESSES = 'persona:HomeAddresses';
+
+ /**
+ * Identifies the HomeCity property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_HOME_CITY = 'persona:HomeCity';
+
+ /**
+ * Identifies the HomeFaxes property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_HOME_FAXES = 'persona:HomeFaxes';
+
+ /**
+ * Identifies the HomePhones property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_HOME_PHONES = 'persona:HomePhones';
+
+ /**
+ * Identifies the HomePhones2 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_HOME_PHONES_2 = 'persona:HomePhones2';
+
+ /**
+ * Identifies the PersonaId property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_ID = 'persona:PersonaId';
+
+ /**
+ * Identifies the ImAddress property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_IM_ADDRESS = 'persona:ImAddress';
+
+ /**
+ * Identifies the ImAddresses property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_IM_ADDRESSES = 'persona:ImAddresses';
+
+ /**
+ * Identifies the ImAddresses2 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_IM_ADDRESSES_2 = 'persona:ImAddresses2';
+
+ /**
+ * Identifies the ImAddresses3 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_IM_ADDRESSES_3 = 'persona:ImAddresses3';
+
+ /**
+ * Identifies the Initials property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_INITIALS = 'persona:Initials';
+
+ /**
+ * Identifies the Locations property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_LOCATIONS = 'persona:Locations';
+
+ /**
+ * Identifies the Managers property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_MANAGERS = 'persona:Managers';
+
+ /**
+ * Identifies the MiddleNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_MIDDLE_NAMES = 'persona:MiddleNames';
+
+ /**
+ * Identifies the MobilePhones property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_MOBILE_PHONES = 'persona:MobilePhones';
+
+ /**
+ * Identifies the MobilePhones2 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_MOBILE_PHONES_2 = 'persona:MobilePhones2';
+
+ /**
+ * Identifies the Nicknames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_NICKNAMES = 'persona:Nicknames';
+
+ /**
+ * Identifies the PersonaObjectStatus property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_OBJECT_STATUS = 'persona:PersonaObjectStatus';
+
+ /**
+ * Identifies the OfficeLocations property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_OFFICE_LOCATIONS = 'persona:OfficeLocations';
+
+ /**
+ * Identifies the OrganizationMainPhones property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_ORGANIZATION_MAIN_PHONES = 'persona:OrganizationMainPhones';
+
+ /**
+ * Identifies the OtherAddresses property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_OTHER_ADDRESSES = 'persona:OtherAddresses';
+
+ /**
+ * Identifies the OtherFaxes property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_OTHER_FAXES = 'persona:OtherFaxes';
+
+ /**
+ * Identifies the OtherPhones2 property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_OTHER_PHONES_2 = 'persona:OtherPhones2';
+
+ /**
+ * Identifies the OtherTelephones property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_OTHER_TELEPHONES = 'persona:OtherTelephones';
+
+ /**
+ * Identifies the Pagers property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_PAGERS = 'persona:Pagers';
+
+ /**
+ * Identifies the PersonalHomePages property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_PERSONAL_HOME_PAGES = 'persona:PersonalHomePages';
+
+ /**
+ * Identifies the PhoneNumber property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_PHONE_NUMBER = 'persona:PhoneNumber';
+
+ /**
+ * Identifies the PostalAddress property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_POSTAL_ADDRESS = 'persona:PostalAddress';
+
+ /**
+ * Identifies the Professions property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_PROFESSIONS = 'persona:Professions';
+
+ /**
+ * Identifies the RadioPhones property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_RADIO_PHONES = 'persona:RadioPhones';
+
+ /**
+ * Identifies the RelevanceScore property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_RELEVANCE_SCORE = 'persona:RelevanceScore';
+
+ /**
+ * Identifies the School property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_SCHOOL = 'persona:School';
+
+ /**
+ * Identifies the SpouseNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_SPOUSE_NAMES = 'persona:SpouseNames';
+
+ /**
+ * Identifies the Surname property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_SURNAME = 'persona:Surname';
+
+ /**
+ * Identifies the Surnames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_SURNAMES = 'persona:Surnames';
+
+ /**
+ * Identifies the TelexNumbers property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_TELEX_NUMBERS = 'persona:TelexNumbers';
+
+ /**
+ * Identifies the Title property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_TITLE = 'persona:Title';
+
+ /**
+ * Identifies the Titles property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_TITLES = 'persona:Titles';
+
+ /**
+ * Identifies the PersonaType property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_TYPE = 'persona:PersonaType';
+
+ /**
+ * Identifies the WeddingAnniversaries property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_WEDDING_ANNIVERSARIES = 'persona:WeddingAnniversaries';
+
+ /**
+ * Identifies the WorkCity property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_WORK_CITY = 'persona:WorkCity';
+
+ /**
+ * Identifies the WorkFaxes property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_WORK_FAXES = 'persona:WorkFaxes';
+
+ /**
+ * Identifies the YomiCompanyName property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_YOMI_COMPANY_NAME = 'persona:YomiCompanyName';
+
+ /**
+ * Identifies the YomiCompanyNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_YOMI_COMPANY_NAMES = 'persona:YomiCompanyNames';
+
+ /**
+ * Identifies the YomiFirstName property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_YOMI_FIRST_NAME = 'persona:YomiFirstName';
+
+ /**
+ * Identifies the YomiFirstNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_YOMI_FIRST_NAMES = 'persona:YomiFirstNames';
+
+ /**
+ * Identifies the YomiLastName property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_YOMI_LAST_NAME = 'persona:YomiLastName';
+
+ /**
+ * Identifies the YomiLastNames property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const PERSONA_YOMI_LAST_NAMES = 'persona:YomiLastNames';
+
+ /**
+ * Identifies the PostedTime property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const POST_ITEM_POSTED_TIME = 'postitem:PostedTime';
+
+ /**
+ * Identifies the ActualWork property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_ACTUAL_WORK = 'task:ActualWork';
+
+ /**
+ * Identifies the AssignedTime property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_ASSIGNED_TIME = 'task:AssignedTime';
+
+ /**
+ * Identifies the BillingInformation property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_BILLING_INFORMATION = 'task:BillingInformation';
+
+ /**
+ * Identifies the ChangeCount property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_CHANGE_COUNT = 'task:ChangeCount';
+
+ /**
+ * Identifies the Companies property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_COMPANIES = 'task:Companies';
+
+ /**
+ * Identifies the CompleteDate property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_COMPLETE_DATE = 'task:CompleteDate';
+
+ /**
+ * Identifies the Contacts property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_CONTACTS = 'task:Contacts';
+
+ /**
+ * Identifies the DelegationState property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_DELEGATION_STATE = 'task:DelegationState';
+
+ /**
+ * Identifies the Delegator property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_DELEGATOR = 'task:Delegator';
+
+ /**
+ * Identifies the DueDate property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_DUE_DATE = 'task:DueDate';
+
+ /**
+ * Identifies the IsAssignmentEditable property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_IS_ASSIGNMENT_EDITABLE = 'task:IsAssignmentEditable';
+
+ /**
+ * Identifies the IsComplete property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_IS_COMPLETE = 'task:IsComplete';
+
+ /**
+ * Identifies the IsRecurring property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_IS_RECURRING = 'task:IsRecurring';
+
+ /**
+ * Identifies the IsTeamTask property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_IS_TEAM_TASK = 'task:IsTeamTask';
+
+ /**
+ * Identifies the Mileage property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_MILEAGE = 'task:Mileage';
+
+ /**
+ * Identifies the Owner property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_OWNER = 'task:Owner';
+
+ /**
+ * Identifies the PercentComplete property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_PERCENT_COMPLETE = 'task:PercentComplete';
+
+ /**
+ * Identifies the Recurrence property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_RECURRENCE = 'task:Recurrence';
+
+ /**
+ * Identifies the StartDate property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_START_DATE = 'task:StartDate';
+
+ /**
+ * Identifies the Status property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_STATUS = 'task:Status';
+
+ /**
+ * Identifies the StatusDescription property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_STATUS_DESCRIPTION = 'task:StatusDescription';
+
+ /**
+ * Identifies the TotalWork property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ const TASK_TOTAL_WORK = 'task:TotalWork';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationDictionaryObjectTypesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationDictionaryObjectTypesType.php
new file mode 100644
index 00000000..f026d487
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationDictionaryObjectTypesType.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\UserConfigurationDictionaryObjectTypesType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines a dictionary object's type.
+ *
+ * @package php-ews\Enumeration
+ */
+class UserConfigurationDictionaryObjectTypesType extends Enumeration
+{
+ /**
+ * Defines the object's type as a boolean.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const BOOLEAN = 'Boolean';
+
+ /**
+ * Defines the object's type as a byte.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const BYTE = 'Byte';
+
+ /**
+ * Defines the object's type as an array of bytes.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const BYTE_ARRAY = 'ByteArray';
+
+ /**
+ * Defines the object's type as a date and time.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DATE_TIME = 'DateTime';
+
+ /**
+ * Defines the object's type as a 32-bit integer.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ CONST INTEGER_32 = 'Integer32';
+
+ /**
+ * Defines the object's type as a 64-bit integer.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const INTEGER_64 = 'Integer64';
+
+ /**
+ * Defines the object's type as a string.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const STRING = 'String';
+
+ /**
+ * Defines the object's type as an array of strings.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const STRING_ARRAY = 'StringArray';
+
+ /**
+ * Defines the object's type as an unsigned 32-bit integer.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNSIGNED_INTEGER_32 = 'UnsignedInteger32';
+
+ /**
+ * Defines the object's type as an unsigned 64-bit integer.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const UNSIGNED_INTEGER_64 = 'UnsignedInteger64';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationPropertyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationPropertyType.php
new file mode 100644
index 00000000..58f6d141
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserConfigurationPropertyType.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\UserConfigurationPropertyType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the property types to get in a GetUserConfiguration operation.
+ *
+ * @package php-ews\Enumeration
+ */
+class UserConfigurationPropertyType extends Enumeration
+{
+ /**
+ * Specifies the identifier, dictionary, XML data, and binary data property
+ * types.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ALL = 'All';
+
+ /**
+ * Specifies binary data property types.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const BINARY_DATA = 'BinaryData';
+
+ /**
+ * Specifies dictionary property types.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const DICTIONARY = 'Dictionary';
+
+ /**
+ * Specifies the identifier property.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const ID = 'Id';
+
+ /**
+ * Specifies XML data property types.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ const XML_DATA = 'XmlData';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoSizeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoSizeType.php
new file mode 100644
index 00000000..0c3661de
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoSizeType.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\UserPhotoSizeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the size of a user's photo being requested.
+ *
+ * @package php-ews\Enumeration
+ */
+class UserPhotoSizeType extends Enumeration
+{
+ /**
+ * The image is 48 pixels high and 48 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR48X48 = 'HR48x48';
+
+ /**
+ * The image is 64 pixels high and 64 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR64X64 = 'HR64x64';
+
+ /**
+ * The image is 96 pixels high and 96 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR96X96 = 'HR96x96';
+
+ /**
+ * The image is 120 pixels high and 120 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR120X120 = 'HR120x120';
+
+ /**
+ * The image is 240 pixels high and 240 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR240X240 = 'HR240x240';
+
+ /**
+ * The image is 360 pixels high and 360 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR360X360 = 'HR360x360';
+
+ /**
+ * The image is 432 pixels high and 432 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR432X432 = 'HR432x432';
+
+ /**
+ * The image is 504 pixels high and 504 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR504X504 = 'HR504x504';
+
+ /**
+ * The image is 648 pixels high and 648 pixels wide.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HR648X648 = 'HR648x648';
+
+ /**
+ * The image is 1024 pixels high and 1024 pixels wide.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ const HR1024XN = 'HR1024xN';
+
+ /**
+ * The image is 1920 pixels high and 1920 pixels wide.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ const HR1920XN = 'HR1920xN';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoTypeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoTypeType.php
new file mode 100644
index 00000000..2477c7ae
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/UserPhotoTypeType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\UserPhotoTypeType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the type of a user photo.
+ *
+ * @package php-ews\Enumeration
+ */
+class UserPhotoTypeType extends Enumeration
+{
+ /**
+ * Identifies a user photo as a profile header photo.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ const PROFILE_HEADER_PHOTO = 'ProfileHeaderPhoto';
+
+ /**
+ * Identifies a user photo as the user's primary photo.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ const USER_PHOTO = 'UserPhoto';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ViewFilterType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ViewFilterType.php
new file mode 100644
index 00000000..06241635
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Enumeration/ViewFilterType.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Enumeration\ViewFilterType.
+ */
+
+namespace jamesiarmes\PhpEws\Enumeration;
+
+use \jamesiarmes\PhpEws\Enumeration;
+
+/**
+ * Defines the view filter type for a FindConversation operation.
+ *
+ * @package php-ews\Enumeration
+ */
+class ViewFilterType extends Enumeration
+{
+ /**
+ * Find all conversations.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const ALL = 'All';
+
+ /**
+ * For internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const CLUTTER = 'Clutter';
+
+ /**
+ * Find flagged conversations.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const FLAGGED = 'Flagged';
+
+ /**
+ * Find conversations with attachments.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const HAS_ATTACHMENT = 'HasAttachment';
+
+ /**
+ * For internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const NO_CLUTTER = 'NoClutter';
+
+ /**
+ * Find active tasks.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TASK_ACTIVE = 'TaskActive';
+
+ /**
+ * Find completed tasks.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TASK_COMPLETED = 'TaskCompleted';
+
+ /**
+ * Find overdue tasks.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TASK_OVERDUE = 'TaskOverdue';
+
+ /**
+ * Find conversations addressed or cc'd to me.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const TO_OR_CC_ME = 'ToOrCcMe';
+
+ /**
+ * Find unread conversations.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ const UNREAD = 'Unread';
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request.php
new file mode 100644
index 00000000..fc14ce7d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request.
+ */
+
+namespace jamesiarmes\PhpEws;
+
+/**
+ * Base class for Exchange Web Service requests.
+ *
+ * @package php-ews\Request
+ */
+abstract class Request extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDelegateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDelegateType.php
new file mode 100644
index 00000000..2d23de0c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDelegateType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\AddDelegateType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to add delegates to a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class AddDelegateType extends BaseDelegateType
+{
+ /**
+ * Contains the identities of delegates to add to or update in a mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfDelegateUserType
+ */
+ public $DelegateUsers;
+
+ /**
+ * Defines how meeting requests are handled between the delegate and the
+ * principal.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DeliverMeetingRequestsType
+ */
+ public $DeliverMeetingRequests;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDistributionGroupToImListType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDistributionGroupToImListType.php
new file mode 100644
index 00000000..6efb10b3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddDistributionGroupToImListType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\AddDistributionGroupToImListType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to add a distribution list to an instant message list.
+ *
+ * @package php-ews\Request
+ */
+class AddDistributionGroupToImListType extends BaseRequestType
+{
+ /**
+ * Contains the display name of a new instant messaging group contact or the
+ * display name of a new instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Represents the Simple Mail Transfer Protocol (SMTP) address of an account
+ * to be used for impersonation or a Simple Mail Transfer Protocol (SMTP)
+ * recipient address of a calendar or contact sharing request.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImContactToGroup.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImContactToGroup.php
new file mode 100644
index 00000000..270a151f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImContactToGroup.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\AddImContactToGroup.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to add an existing instant messaging contact to an instant
+ * messaging group.
+ *
+ * @package php-ews\Request
+ */
+class AddImContactToGroup extends BaseRequestType
+{
+ /**
+ * Uniquely identifies a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ContactId;
+
+ /**
+ * Uniquely identifies a group.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $GroupId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImGroupType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImGroupType.php
new file mode 100644
index 00000000..834c3216
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddImGroupType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\AddImGroupType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to add a new instant messaging group.
+ *
+ * @package php-ews\Request
+ */
+class AddImGroupType extends BaseRequestType
+{
+ /**
+ * Display name of the instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewImContactToGroup.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewImContactToGroup.php
new file mode 100644
index 00000000..f1a3ff2d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewImContactToGroup.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\AddNewImContactToGroup.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to add a new instant messaging contact to an instant
+ * messaging group.
+ *
+ * @package php-ews\Request
+ */
+class AddNewImContactToGroup extends BaseRequestType
+{
+ /**
+ * Contains the display name of a new instant messaging group contact or the
+ * display name of a new instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Unique identifier of a group.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $GroupId;
+
+ /**
+ * Contains the instant messaging address of a new contact that will be
+ * added to an instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ImAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewTelUriContactToGroupType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewTelUriContactToGroupType.php
new file mode 100644
index 00000000..bdee20bd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/AddNewTelUriContactToGroupType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\AddNewTelUriContactToGroupType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to add a contact to a group based on the contacts phone
+ * number.
+ *
+ * @package php-ews\Request
+ */
+class AddNewTelUriContactToGroupType extends BaseRequestType
+{
+ /**
+ * Unique identifier of a group.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $GroupId;
+
+ /**
+ * Contains the SIP URI address of a contact that is added to an instant
+ * messaging (IM) group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ImContactSipUriAddress;
+
+ /**
+ * Represents the telephone number for a contact that is added to an instant
+ * messaging (IM) group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ImTelephoneNumber;
+
+ /**
+ * Contains the tel Uniform Resource Identifier (URI) for a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $TelUriAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ApplyConversationActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ApplyConversationActionType.php
new file mode 100644
index 00000000..4424bdbf
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ApplyConversationActionType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\ApplyConversationActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to apply actions to items in a conversation.
+ *
+ * @package php-ews\Request
+ */
+class ApplyConversationActionType extends BaseRequestType
+{
+ /**
+ * Contains a collection of conversations and the actions to apply to them.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfApplyConversationActionType
+ */
+ public $ConversationActions;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ArchiveItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ArchiveItemType.php
new file mode 100644
index 00000000..f4043ac9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ArchiveItemType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\ArchiveItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the source folder Id and an array of item Ids for the associated
+ * archive item.
+ *
+ * @package php-ews\Request
+ */
+class ArchiveItemType extends BaseRequestType
+{
+ /**
+ * Specifies the Id of the source folder for the archive item.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ArchiveSourceFolderId;
+
+ /**
+ * Contains the unique identities of items to archive.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ItemIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseDelegateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseDelegateType.php
new file mode 100644
index 00000000..66b82bb3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseDelegateType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\BaseDelegateType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Base class for delegate requests.
+ *
+ * @package php-ews\Request
+ */
+abstract class BaseDelegateType extends BaseRequestType
+{
+ /**
+ * Identifies the principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyFolderType.php
new file mode 100644
index 00000000..95c9d0e9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyFolderType.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\BaseMoveCopyFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Base class for folder move and copy requests.
+ *
+ * @package php-ews\Request
+ */
+class BaseMoveCopyFolderType extends BaseRequestType
+{
+ /**
+ * Represents the destination folder for a copied folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FolderIds;
+
+ /**
+ * Represents the destination folder for a copied folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ToFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyItemType.php
new file mode 100644
index 00000000..8cb7af69
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseMoveCopyItemType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\BaseMoveCopyItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Base class for item copy and move operations.
+ *
+ * @package php-ews\Request
+ */
+class BaseMoveCopyItemType extends BaseRequestType
+{
+ /**
+ * Contains an array of identified items to copy or move to the folder
+ * represented by the ToFolderId element.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ItemIds;
+
+ /**
+ * Indicates whether the item identifiers of new items are returned in the
+ * response.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $ReturnNewItemIds;
+
+ /**
+ * Represents the destination folder for the items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ToFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseRequestType.php
new file mode 100644
index 00000000..40ae2743
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/BaseRequestType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\BaseRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+use \jamesiarmes\PhpEws\Request;
+
+/**
+ * Base class for requests.
+ *
+ * @package php-ews\Request
+ */
+abstract class BaseRequestType extends Request
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ConvertIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ConvertIdType.php
new file mode 100644
index 00000000..9d06bc38
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ConvertIdType.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\ConvertIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+use \jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to convert item and folder identifiers between supported
+ * Exchange formats.
+ *
+ * @package php-ews\Request
+ */
+class ConvertIdType extends BaseRequestType
+{
+ /**
+ * Describes the identifier format that will be returned for all the
+ * converted identifiers.
+ *
+ * The DestinationFormat is described by the IdFormatType.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\IdFormatType
+ */
+ public $DestinationFormat;
+
+ /**
+ * Contains the source identifiers to convert.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAlternateIdsType
+ */
+ public $SourceIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyFolderType.php
new file mode 100644
index 00000000..413f0c55
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyFolderType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CopyFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to copy folders in a mailbox in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class CopyFolderType extends BaseMoveCopyFolderType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyItemType.php
new file mode 100644
index 00000000..0b8bd4ad
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CopyItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CopyItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to copy an item in a mailbox in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class CopyItemType extends BaseMoveCopyItemType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateAttachmentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateAttachmentType.php
new file mode 100644
index 00000000..b629698e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateAttachmentType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CreateAttachmentType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to create an attachment to an item in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class CreateAttachmentType extends BaseRequestType
+{
+ /**
+ * Contains the items or files to attach to an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfAttachmentsType
+ */
+ public $Attachments;
+
+ /**
+ * Identifies the parent Exchange store item that contains the created
+ * attachment.
+ *
+ * The ParentItemId element must provide the ID of a real Exchange store
+ * item. Real store items can be retrieved by using the GetItem operation;
+ * attachments are retrieved by using the GetAttachment operation. An error
+ * occurs if the ParentItemId is passed the ID of a file attachment. If the
+ * ParentItemId represents the ID of an existing item attachment, the
+ * CreateAttachment operation adds the new attachment to the existing
+ * attachment.
+ *
+ * This element is required.
+ *
+ * The following item attachments can be created:
+ * - Item
+ * - Message
+ * - CalendarItem
+ * - Contact
+ * - Task
+ * - MeetingMessage
+ * - MeetingRequest
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ParentItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderPathType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderPathType.php
new file mode 100644
index 00000000..6ceb65b5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderPathType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CreateFolderPathType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to create a folder path.
+ *
+ * @package php-ews\Request
+ */
+class CreateFolderPathType extends BaseRequestType
+{
+ /**
+ * Identifies the folder in which a new folder is created.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ParentFolderId;
+
+ /**
+ * Contains an array of folders that indicate the relative folder path of
+ * the folder path to be created.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFoldersType
+ */
+ public $RelativeFolderPath;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderType.php
new file mode 100644
index 00000000..d153812c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateFolderType.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CreateFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to create a folder in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class CreateFolderType extends BaseRequestType
+{
+ /**
+ * The element that contains all the folders to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFoldersType
+ */
+ public $Folders;
+
+ /**
+ * The element that identifies the location where the new folder is created.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ParentFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateItemType.php
new file mode 100644
index 00000000..098b46c3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateItemType.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CreateItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to create an item in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class CreateItemType extends BaseRequestType
+{
+ /**
+ * Contains an array of items to create in the folder that is identified by
+ * the SavedItemFolderId element.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType
+ */
+ public $Items;
+
+ /**
+ * Describes how the item will be handled after it is created.
+ *
+ * This attribute is only applicable to e-mail messages.
+ *
+ * The attribute is required for e-mail messages.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MessageDispositionType
+ */
+ public $MessageDisposition;
+
+ /**
+ * Identifies the target folder where a new item can be created.
+ *
+ * If the MessageDisposition attribute is set to SendOnly, a created message
+ * will only be sent. The message will not be put in the folder that is
+ * identified by the SavedItemFolderId element.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $SavedItemFolderId;
+
+ /**
+ * Describes how meeting requests are handled after they are created.
+ *
+ * This attribute is required for calendar items.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarItemCreateOrDeleteOperationType
+ */
+ public $SendMeetingInvitations;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateManagedFolderRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateManagedFolderRequestType.php
new file mode 100644
index 00000000..85897304
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateManagedFolderRequestType.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CreateManagedFolderRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to add managed custom folders to a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class CreateManagedFolderRequestType extends BaseRequestType
+{
+ /**
+ * Contains an array of named managed folders to add to a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFolderNamesType
+ */
+ public $FolderNames;
+
+ /**
+ * Identifies a mail-enabled Active Directory directory service object.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateUserConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateUserConfigurationType.php
new file mode 100644
index 00000000..114c4c58
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/CreateUserConfigurationType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\CreateUserConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to create a user configuration object.
+ *
+ * @package php-ews\Request
+ */
+class CreateUserConfigurationType extends BaseRequestType
+{
+ /**
+ * Represents a single user configuration object.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationType
+ */
+ public $UserConfiguration;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteAttachmentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteAttachmentType.php
new file mode 100644
index 00000000..c6b5a3aa
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteAttachmentType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\DeleteAttachmentType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to delete an attachment from the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class DeleteAttachmentType extends BaseRequestType
+{
+ /**
+ * Contains an array of attachment identifiers that are used to delete the
+ * attachments.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfRequestAttachmentIdsType
+ */
+ public $AttachmentIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteFolderType.php
new file mode 100644
index 00000000..74a9d0f5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteFolderType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\DeleteFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to delete folders from a mailbox in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class DeleteFolderType extends BaseRequestType
+{
+ /**
+ * Describes how a folder is deleted. This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DisposalType
+ */
+ public $DeleteType;
+
+ /**
+ * Contains an array of folder identifiers that are used to identify folders
+ * to delete.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FolderIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteItemType.php
new file mode 100644
index 00000000..a36a99b1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteItemType.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\DeleteItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to delete an item from a mailbox in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class DeleteItemType extends BaseRequestType
+{
+ /**
+ * Describes whether a task instance or a task master is deleted by a
+ * DeleteItem operation.
+ *
+ * This attribute is required when tasks are deleted.
+ *
+ * This attribute is optional when non-task items are deleted.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\AffectedTaskOccurrencesType
+ */
+ public $AffectedTaskOccurrences;
+
+ /**
+ * Describes how an item is deleted.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DisposalType
+ */
+ public $DeleteType;
+
+ /**
+ * Contains an array of items, occurrence items, and recurring master items
+ * to delete from a mailbox in the Exchange store.
+ *
+ * The DeleteItem operation can be performed on any item type.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ItemIds;
+
+ /**
+ * Describes whether a calendar item deletion is communicated to attendees.
+ *
+ * This attribute is required when calendar items are deleted.
+ *
+ * This attribute is optional if non-calendar items are deleted.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarItemCreateOrDeleteOperationType
+ */
+ public $SendMeetingCancellations;
+
+ /**
+ * Indicates whether read receipts for the deleted item are suppressed.
+ *
+ * A value of true indicates that the read receipts are suppressed. A value
+ * of false indicates that the read receipts are sent to the sender.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $SuppressReadReceipts;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteUserConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteUserConfigurationType.php
new file mode 100755
index 00000000..3e8535a8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DeleteUserConfigurationType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\DeleteUserConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to delete a user configuration object.
+ *
+ * @package php-ews\Request
+ */
+class DeleteUserConfigurationType extends BaseRequestType
+{
+ /**
+ * Represents the name of the user configuration object to delete.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationNameType
+ */
+ public $UserConfigurationName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisableAppType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisableAppType.php
new file mode 100644
index 00000000..1c23b15a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisableAppType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\DisableAppType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to disable an app.
+ *
+ * @package php-ews\Request
+ */
+class DisableAppType extends BaseRequestType
+{
+ /**
+ * Specifies the reason for disabling an app.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DisableReasonType
+ */
+ public $DisableReason;
+
+ /**
+ * Specifies the identifier of an item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ID;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisconnectPhoneCallType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisconnectPhoneCallType.php
new file mode 100644
index 00000000..7ea19064
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/DisconnectPhoneCallType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\DisconnectPhoneCallType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to disconnect a call.
+ *
+ * @package php-ews\Request
+ */
+class DisconnectPhoneCallType extends BaseRequestType
+{
+ /**
+ * Specifies the identifier of the call to disconnect.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhoneCallIdType
+ */
+ public $PhoneCallId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/EmptyFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/EmptyFolderType.php
new file mode 100644
index 00000000..27505c53
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/EmptyFolderType.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\EmptyFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to empty a folder in a mailbox in the Exchange store.
+ *
+ * Optionally, subfolders can also be deleted when the folder is emptied.
+ *
+ * @package php-ews\Request
+ */
+class EmptyFolderType extends BaseRequestType
+{
+ /**
+ * Specifies whether subfolders are to be deleted.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $DeleteSubFolders;
+
+ /**
+ * Specifies how a folder is emptied.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DisposalType
+ */
+ public $DeleteType;
+
+ /**
+ * Array of folder identifiers that are used to identify folders to delete.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FolderIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExpandDLType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExpandDLType.php
new file mode 100644
index 00000000..3fd13660
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExpandDLType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\ExpandDLType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to expand a distribution list.
+ *
+ * @package php-ews\Request
+ */
+class ExpandDLType extends BaseRequestType
+{
+ /**
+ * Identifies a fully resolved e-mail address of a distribution list.
+ *
+ * This mailbox represents the distribution list to expand.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExportItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExportItemsType.php
new file mode 100644
index 00000000..9d84200a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ExportItemsType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\ExportItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to export items from a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class ExportItemsType extends BaseRequestType
+{
+ /**
+ * Contains an array of item identifiers that identify the items to export
+ * from a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemIdsType
+ */
+ public $ItemIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindConversationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindConversationType.php
new file mode 100755
index 00000000..d96a993b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindConversationType.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\FindConversationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to find conversations in a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class FindConversationType extends BaseRequestType
+{
+ /**
+ * Identifies the property set to return in a FindConversation operation
+ * response.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConversationShape
+ */
+ public $ConversationShape;
+
+ /**
+ * Describes how paged conversation information is returned.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\IndexedPageViewType
+ */
+ public $IndexedPageItemView;
+
+ /**
+ * Specifies whether a search or fetch for a conversation should span either
+ * the primary mailbox, archive mailbox, or both the primary and archive
+ * mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MailboxSearchLocationType
+ */
+ public $MailboxScope;
+
+ /**
+ * Identifies the folder to search for conversations.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ParentFolderId;
+
+ /**
+ * Specifies a mailbox query string based on Advanced Query Syntax (AQS).
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\QueryStringType
+ */
+ public $QueryString;
+
+ /**
+ * Specifies the condition that is used to identify the end of a search, the
+ * starting index of a search, the maximum entries to return, and the search
+ * directions for a FindItem or FindConversation search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\SeekToConditionPageViewType
+ */
+ public $SeekToConditionPageItemView;
+
+ /**
+ * Defines how items are sorted in a FindConversation Operation request.
+ *
+ * The conversation:LastDeliveryTime property is the only property that is
+ * supported for sorting when the FindConversation operation is used.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFieldOrdersType
+ */
+ public $SortOrder;
+
+ /**
+ * Identifies the types of sub-tree traversal.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConversationQueryTraversalType
+ */
+ public $Traversal;
+
+ /**
+ * Identifies the types view filters.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ViewFilterType
+ */
+ public $ViewFilter;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindFolderType.php
new file mode 100644
index 00000000..6b74d7eb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindFolderType.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\FindFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to find folders in a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class FindFolderType extends BaseRequestType
+{
+ /**
+ * Identifies the folder properties to include in a FindFolder response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderResponseShapeType
+ */
+ public $FolderShape;
+
+ /**
+ * Describes where the paged view starts and the maximum number of folders
+ * returned in a FindFolder request.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FractionalPageViewType
+ */
+ public $FractionalPageFolderView;
+
+ /**
+ * Describes how paged item information is returned in a FindFolder
+ * response.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IndexedPageViewType
+ */
+ public $IndexedPageFolderView;
+
+ /**
+ * Identifies folders for the FindFolder operation to search.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $ParentFolderIds;
+
+ /**
+ * Defines a restriction or query that is used to filter folders in a
+ * FindFolder operation.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RestrictionType
+ */
+ public $Restriction;
+
+ /**
+ * Defines how a search is performed.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\FolderQueryTraversalType
+ */
+ public $Traversal;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindItemType.php
new file mode 100644
index 00000000..21b47bf6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindItemType.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\FindItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to find items in a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class FindItemType extends BaseRequestType
+{
+ /**
+ * Provides time span limits to define a search for calendar items.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarViewType
+ */
+ public $CalendarView;
+
+ /**
+ * Defines a search for contact items based on alphabetical display names.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactsViewType
+ */
+ public $ContactsView;
+
+ /**
+ * Provides standard groupings for FindItem queries.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistinguishedGroupByType
+ */
+ public $DistinguishedGroupBy;
+
+ /**
+ * Describes where the paged view starts and the maximum number of items
+ * returned in a FindItem request.
+ *
+ * The paged view offset from the beginning of the set of found items is
+ * described by a fraction.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FractionalPageViewType
+ */
+ public $FractionalPageItemView;
+
+ /**
+ * Specifies arbitrary groupings for FindItem queries.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\GroupByType
+ */
+ public $GroupBy;
+
+ /**
+ * Describes how paged item information is returned for a FindItem request.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IndexedPageViewType
+ */
+ public $IndexedPageItemView;
+
+ /**
+ * Identifies the item properties and content to include in a FindItem
+ * operation response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemResponseShapeType
+ */
+ public $ItemShape;
+
+ /**
+ * Identifies folders to search for the FindItem and FindFolder operations.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $ParentFolderIds;
+
+ /**
+ * Contains a mailbox query string based on Advanced Query Syntax (AQS).
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\QueryStringType
+ */
+ public $QueryString;
+
+ /**
+ * Defines the restriction or query that is used to filter items or folders
+ * in FindItem/FindFolder and search folder operations.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RestrictionType
+ */
+ public $Restriction;
+
+ /**
+ * Defines how items are sorted in a FindItem request.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFieldOrdersType
+ */
+ public $SortOrder;
+
+ /**
+ * Defines whether the search finds items in folders or the folders'
+ * dumpsters.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ItemQueryTraversalType
+ */
+ public $Traversal;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMailboxStatisticsByKeywordsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMailboxStatisticsByKeywordsType.php
new file mode 100644
index 00000000..65154d09
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMailboxStatisticsByKeywordsType.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\FindMailboxStatisticsByKeywordsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to search for mailbox statistics by keyword.
+ *
+ * @package php-ews\Request
+ */
+class FindMailboxStatisticsByKeywordsType extends BaseRequestType
+{
+ /**
+ * Specifies the date that the message was sent.Specifies an array of
+ * recipients of a message.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $FromDate;
+
+ /**
+ * Specifies whether to include the personal archive in the search.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IncludePersonalArchive;
+
+ /**
+ * Specifies whether to include items that cannot be searched.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IncludeUnsearchableItems;
+
+ /**
+ * Specifies keywords for a search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Keywords;
+
+ /**
+ * Contains the language used for the search query.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Language;
+
+ /**
+ * Contains an array of mailboxes affected by the hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfUserMailboxesType
+ */
+ public $Mailboxes;
+
+ /**
+ * Specifies an array of messages to search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSearchItemKindsType
+ */
+ public $MessageTypes;
+
+ /**
+ * Specifies an array of recipients of a message.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSmtpAddressType
+ */
+ public $Recipients;
+
+ /**
+ * Specifies whether to search in deleted items.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $SearchDumpster;
+
+ /**
+ * Specifies an array of SMTP addresses.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSmtpAddressType
+ */
+ public $Senders;
+
+ /**
+ * Specifies the date that the message was received.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $ToDate;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMessageTrackingReportRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMessageTrackingReportRequestType.php
new file mode 100644
index 00000000..c9dfa398
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindMessageTrackingReportRequestType.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\FindMessageTrackingReportRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents criteria for the types of messages to find.
+ *
+ * @package php-ews\Request
+ */
+class FindMessageTrackingReportRequestType extends BaseRequestType
+{
+ /**
+ * Represents the level of detail for diagnostic reports.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $DiagnosticsLevel;
+
+ /**
+ * Contains the name of the domain where the message tracking is executed.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Domain;
+
+ /**
+ * Contains the ending date and time for the search.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $EndDateTime;
+
+ /**
+ * Contains the name of the mailbox where the cross-premise message was
+ * sent.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $FederatedDeliveryMailbox;
+
+ /**
+ * Contains the message identifier for the search.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $MessageId;
+
+ /**
+ * Contains a list of one or more tracking properties.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType
+ */
+ public $Properties;
+
+ /**
+ * Contains contact information for the alleged sender of an e-mail message.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $PurportedSender;
+
+ /**
+ * Contains the e-mail address for the recipient of the message.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Recipient;
+
+ /**
+ * Represents how extensive the message tracking report should be.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\Scope
+ */
+ public $Scope;
+
+ /**
+ * Contains contact information for the sender of the e-mail message.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Sender;
+
+ /**
+ * Represents the starting point for tracking a message in a remote site or
+ * forest.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $ServerHint;
+
+ /**
+ * Contains the starting date and time for the search.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $StartDateTime;
+
+ /**
+ * Contains the subject of the e-mail message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Subject;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindPeopleType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindPeopleType.php
new file mode 100644
index 00000000..6e8c1699
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/FindPeopleType.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\FindPeopleType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a set of data used in a FindPeople request.
+ *
+ * @package php-ews\Request
+ */
+class FindPeopleType extends BaseRequestType
+{
+ /**
+ * Specifies a value that is applied to a set of Persona properties.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\RestrictionType
+ */
+ public $AggregationRestriction;
+
+ /**
+ * Specifies the context properties of the contact.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfContextProperty
+ */
+ public $Context;
+
+ /**
+ * Describes how paged conversation or item information is returned.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\IndexedPageViewType
+ */
+ public $IndexedPageItemView;
+
+ /**
+ * Identifies the folder in which to search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ParentFolderId;
+
+ /**
+ * Specifies the set of persona properties.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaResponseShapeType
+ */
+ public $PersonaShape;
+
+ /**
+ * Specifies the source data for the query.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPeopleQuerySource
+ */
+ public $QuerySources;
+
+ /**
+ * Contains a mailbox query string based on Advanced Query Syntax (AQS).
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\QueryStringType
+ */
+ public $QueryString;
+
+ /**
+ * Represents the restriction or query that is used to filter items.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\RestrictionType
+ */
+ public $Restriction;
+
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ */
+ public $SearchPeopleSuggestionIndex;
+
+ /**
+ * Defines how items are sorted.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFieldOrdersType
+ */
+ public $SortOrder;
+
+ /**
+ * Specifies the query string for topic searches.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ public $TopicQueryString;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppManifestsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppManifestsType.php
new file mode 100644
index 00000000..cc5a4735
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppManifestsType.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetAppManifestsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Base element for a request to return the manifest for apps.
+ *
+ * @package php-ews\Request
+ */
+class GetAppManifestsType extends BaseRequestType
+{
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPrivateCatalogAddInsType
+ *
+ * @todo Update once documentation exists.
+ */
+ public $AddIns;
+
+ /**
+ * Contains the version of the JavaScript API for Office supported by the
+ * client.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ public $ApiVersionSupported;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ * @todo Determine if we need a ListOfExtensionIdsType implementation.
+ */
+ public $ExtensionIds;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ *
+ * @todo Update once documentation exists.
+ */
+ public $IncludeAllInstalledAddIns;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ *
+ * @todo Update once documentation exists.
+ */
+ public $IncludeCustomAppsData;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ *
+ * @todo Update once documentation exists.
+ */
+ public $IncludeEntitlementData;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ *
+ * @todo Update once documentation exists.
+ */
+ public $IncludeManifestData;
+
+ /**
+ * Contains the version of the manifest schema supported by the client.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ public $SchemaVersionSupported;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppMarketplaceUrl.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppMarketplaceUrl.php
new file mode 100644
index 00000000..ccc8fc29
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAppMarketplaceUrl.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetAppMarketplaceUrl.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to retrieve the URL for the app marketplace.
+ *
+ * @package php-ews\Request
+ */
+class GetAppMarketplaceUrl extends BaseRequestType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAttachmentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAttachmentType.php
new file mode 100755
index 00000000..f373111c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetAttachmentType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetAttachmentType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get an attachment from the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class GetAttachmentType extends BaseRequestType
+{
+ /**
+ * Contains an array of attachment identifiers.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfRequestAttachmentIdsType
+ */
+ public $AttachmentIds;
+
+ /**
+ * Identifies additional extended item properties to return in a response to
+ * a GetAttachment request.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AttachmentResponseShapeType
+ */
+ public $AttachmentShape;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetClientAccessTokenType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetClientAccessTokenType.php
new file mode 100644
index 00000000..345db358
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetClientAccessTokenType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetClientAccessTokenType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get a client access token.
+ *
+ * @package php-ews\Request
+ */
+class GetClientAccessTokenType extends BaseRequestType
+{
+ /**
+ * Contains an array of token requests.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfClientAccessTokenRequestsType
+ */
+ public $TokenRequests;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetConversationItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetConversationItemsType.php
new file mode 100644
index 00000000..5a9f2cc6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetConversationItemsType.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetConversationItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get a set of items that are related by being in the same
+ * conversation.
+ *
+ * @package php-ews\Request
+ */
+class GetConversationItemsType extends BaseRequestType
+{
+ /**
+ * Contains an array of conversations to get items for.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfConversationsType
+ */
+ public $Conversations;
+
+ /**
+ * Identifies a list of folders that are ignored when getting items in a
+ * conversation.
+ *
+ * All conversation items in the ignored folders are not returned in the
+ * response.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FoldersToIgnore;
+
+ /**
+ * Identifies a set of properties to return.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemResponseShapeType
+ */
+ public $ItemShape;
+
+ /**
+ * Identifies whether a search or fetch for a conversation should span
+ * either the primary mailbox, archive mailbox, or both the primary and
+ * archive mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MailboxSearchLocationType
+ */
+ public $MailboxScope;
+
+ /**
+ * Identifies the maximum number of conversations items to return.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $MaxItemsToReturn;
+
+ /**
+ * Specifies the sort order used for the result.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConversationNodeSortOrder
+ */
+ public $SortOrder;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDelegateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDelegateType.php
new file mode 100644
index 00000000..2d2a1dc9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDelegateType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetDelegateType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get information about delegates to a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class GetDelegateType extends BaseDelegateType
+{
+ /**
+ * Indicates whether the response contains permission settings for each
+ * delegate user.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $IncludePermissions;
+
+ /**
+ * Contains an array of delegate users to get from a principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfUserIdType
+ */
+ public $UserIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDiscoverySearchConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDiscoverySearchConfigurationType.php
new file mode 100644
index 00000000..944bc0db
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetDiscoverySearchConfigurationType.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetDiscoverySearchConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to retrieve the eDiscovery search configuration.
+ *
+ * @package php-ews\Request
+ */
+class GetDiscoverySearchConfigurationType extends BaseRequestType
+{
+ /**
+ * Contains a Boolean value that indicates whether to expand the membership
+ * of the group returned from a GetSearchableMailboxes request.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $ExpandGroupMembership;
+
+ /**
+ * Specifies whether to include the in-place hold configuration.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $InPlaceHoldConfigurationOnly;
+
+ /**
+ * Specifies the identifier of the search.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SearchId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetEventsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetEventsType.php
new file mode 100755
index 00000000..d26dfbde
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetEventsType.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetEventsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents the operation used by pull clients to request notifications from
+ * the server.
+ *
+ * @package php-ews\Request
+ */
+class GetEventsType extends BaseRequestType
+{
+ /**
+ * Represents the identifier for a subscription that is queried for events.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SubscriptionId;
+
+ /**
+ * Represents the last watermark returned to the client.
+ *
+ * If GetEvents has not been called for this subscription, the client uses
+ * the watermark returned from the Subscribe request. Otherwise, the
+ * watermark from the last event in the last GetEvents response is used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Determine if we need a WatermarkType.
+ */
+ public $Watermark;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetFolderType.php
new file mode 100644
index 00000000..40112a26
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetFolderType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get a folder from a mailbox in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class GetFolderType extends BaseRequestType
+{
+ /**
+ * Contains an array of folder identifiers that are used to identify folders
+ * to get from a mailbox in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FolderIds;
+
+ /**
+ * Identifies the properties to get for each folder identified in the
+ * FolderIds element.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderResponseShapeType
+ */
+ public $FolderShape;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetHoldOnMailboxesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetHoldOnMailboxesType.php
new file mode 100644
index 00000000..05048a76
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetHoldOnMailboxesType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetHoldOnMailboxesType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get the hold status for a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class GetHoldOnMailboxesType extends BaseRequestType
+{
+ /**
+ * Contains the mailbox hold identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $HoldId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemListType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemListType.php
new file mode 100644
index 00000000..c7be93b7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemListType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetImItemListType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get a list of instant messaging groups and contacts.
+ *
+ * @package php-ews\Request
+ */
+class GetImItemListType extends BaseRequestType
+{
+ /**
+ * Contains any extended properties used for the request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfExtendedFieldURIs
+ */
+ public $ExtendedProperties;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemsType.php
new file mode 100644
index 00000000..f99da563
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetImItemsType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetImItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get information about the specified instant messaging
+ * groups and instant messaging contact personas.
+ *
+ * @package php-ews\Request
+ */
+class GetImItemsType extends BaseRequestType
+{
+ /**
+ * Contains an array of contact item identifiers.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ContactIds;
+
+ /**
+ * Identifies an array of instant messaging group identifiers.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $GroupIds;
+
+ /**
+ * Contains the extended properties used for the Unified Contact Store
+ * operations.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfExtendedFieldURIs
+ */
+ public $ExtendedProperties;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetInboxRulesRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetInboxRulesRequestType.php
new file mode 100644
index 00000000..2388eec6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetInboxRulesRequestType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetInboxRulesRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get the Inbox rules on a mailbox in the server store.
+ *
+ * @package php-ews\Request
+ */
+class GetInboxRulesRequestType extends BaseRequestType
+{
+ /**
+ * Represents the SMTP address of the user whose Inbox rules are to be
+ * retrieved.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $MailboxSmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetItemType.php
new file mode 100644
index 00000000..eeb3e7e3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetItemType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get an item from a mailbox in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class GetItemType extends BaseRequestType
+{
+ /**
+ * Contains the unique identities of items, occurrence items, and recurring
+ * master items that are used to get items from the Exchange store.
+ *
+ * These items represent contacts, tasks, messages, calendar items, meeting
+ * requests, and other valid items in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ItemIds;
+
+ /**
+ * Identifies the item properties and content to include in a GetItem
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemResponseShapeType
+ */
+ public $ItemShape;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMailTipsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMailTipsType.php
new file mode 100644
index 00000000..06f953ac
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMailTipsType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetMailTipsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents the recipients and types of mail tips to retrieve.
+ *
+ * @package php-ews\Request
+ */
+class GetMailTipsType extends BaseRequestType
+{
+ /**
+ * Contains the types of mail tips requested from the service.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MailTipTypes
+ */
+ public $MailTipsRequested;
+
+ /**
+ * Contains a list of recipients to check for mail tips.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $Recipients;
+
+ /**
+ * Contains an e-mail address that a user is trying to send as.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $SendingAs;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMessageTrackingReportRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMessageTrackingReportRequestType.php
new file mode 100644
index 00000000..227ecc49
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetMessageTrackingReportRequestType.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetMessageTrackingReportRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents the request for the GetMessageTrackingReport Operation to retrieve
+ * the full message tracking report for the specified ID.
+ *
+ * @package php-ews\Request
+ */
+class GetMessageTrackingReportRequestType extends BaseRequestType
+{
+ /**
+ * Specifies where to perform the search.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\Scope
+ */
+ public $Scope;
+
+ /**
+ * Specifies the type of tracking report to retrieve.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MessageTrackingReportTemplateType
+ */
+ public $ReportTemplate;
+
+ /**
+ * Specifies a recipient address to use with the specified tracking report.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $RecipientFilter;
+
+ /**
+ * Specifies an identity string that was obtained from the
+ * FindMessageTrackingReport operation.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $MessageTrackingReportId;
+
+ /**
+ * Specifies that the person who is running the task has a privileged role.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $ReturnQueueEvents;
+
+ /**
+ * Specifies timing and performance information that will be used to derive
+ * the tracking report. This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $DiagnosticsLevel;
+
+ /**
+ * Specifies a list of one or more tracking properties.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType
+ */
+ public $Properties;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemDetailsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemDetailsType.php
new file mode 100644
index 00000000..7e05ca98
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemDetailsType.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetNonIndexableItemDetailsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to retrieve non-indexable item details.
+ *
+ * @package php-ews\Request
+ */
+class GetNonIndexableItemDetailsType extends BaseRequestType
+{
+ /**
+ * Specifies an array of Mailbox elements.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayofLegacyDNsType
+ */
+ public $Mailboxes;
+
+ /**
+ * Contains the direction for pagination in the search result.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SearchPageDirectionType
+ */
+ public $PageDirection;
+
+ /**
+ * Specifies the reference for a page item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $PageItemReference;
+
+ /**
+ * Contains the number of items to be returned in a single page for a search
+ * result.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $PageSize;
+
+ /**
+ * Whether or not to search archive folders only.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $SearchArchiveOnly;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemStatisticsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemStatisticsType.php
new file mode 100644
index 00000000..f9183000
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetNonIndexableItemStatisticsType.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetNonIndexableItemStatisticsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to retrieve non-indexable item statistics.
+ *
+ * @package php-ews\Request
+ */
+class GetNonIndexableItemStatisticsType extends BaseRequestType
+{
+ /**
+ * Specifies an array of Mailbox elements.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayofLegacyDNsType
+ */
+ public $Mailboxes;
+
+ /**
+ * Whether or not to search archive folders only.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $SearchArchiveOnly;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPasswordExpirationDateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPasswordExpirationDateType.php
new file mode 100644
index 00000000..99f1266a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPasswordExpirationDateType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetPasswordExpirationDateType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get the password expiration date for an email account.
+ *
+ * @package php-ews\Request
+ */
+class GetPasswordExpirationDateType extends BaseRequestType
+{
+ /**
+ * Represents the email address of the email account for which the password
+ * expiration date is to be returned.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $MailboxSmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPersonaType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPersonaType.php
new file mode 100644
index 00000000..9b4b7e39
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPersonaType.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetPersonaType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get a persona.
+ *
+ * @package php-ews\Request
+ */
+class GetPersonaType extends BaseRequestType
+{
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType
+ *
+ * @todo Update once documentation exists.
+ */
+ public $AdditionalProperties;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ *
+ * @todo Update once documentation exists.
+ */
+ public $EmailAddress;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ItemLinkId;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ParentFolderId;
+
+ /**
+ * Specifies the persona identifier for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $PersonaId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPhoneCallInformationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPhoneCallInformationType.php
new file mode 100644
index 00000000..27fb10fb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetPhoneCallInformationType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetPhoneCallInformationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to get telephone call information.
+ *
+ * @package php-ews\Request
+ */
+class GetPhoneCallInformationType extends BaseRequestType
+{
+ /**
+ * Specifies the identifier of a phone call.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhoneCallIdType
+ */
+ public $PhoneCallId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRemindersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRemindersType.php
new file mode 100644
index 00000000..ffeddb99
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRemindersType.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetRemindersType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get reminders.
+ *
+ * @package php-ews\Request
+ */
+class GetRemindersType extends BaseRequestType
+{
+ /**
+ * Specifies the beginning of the time span to query for reminders.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $BeginTime;
+
+ /**
+ * Represents the end of the time span to query for reminders.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $EndTime;
+
+ /**
+ * Specifies the maximum number of items to return in the request.
+ *
+ * This number cannot be less than zero or greater than 200.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $MaxItems;
+
+ /**
+ * Specifies the type of reminders to return.
+ *
+ * Possible values are All, Current, or Old.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ReminderType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomListsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomListsType.php
new file mode 100644
index 00000000..0f18625f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomListsType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetRoomListsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request for a list of email addresses that represent a list of
+ * available rooms.
+ *
+ * @package php-ews\Request
+ */
+class GetRoomListsType extends BaseRequestType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomsType.php
new file mode 100755
index 00000000..9a4c634a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetRoomsType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetRoomsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to get a list of rooms within a particular room list.
+ *
+ * @package php-ews\Request
+ */
+class GetRoomsType extends BaseRequestType
+{
+ /**
+ * Represents an e-mail address that identifies a list of meeting rooms.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $RoomList;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSearchableMailboxesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSearchableMailboxesType.php
new file mode 100644
index 00000000..a48d24fb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSearchableMailboxesType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetSearchableMailboxesType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get a list of mailboxes that the client has permission
+ * to perform an eDiscovery search on.
+ *
+ * @package php-ews\Request
+ */
+class GetSearchableMailboxesType extends BaseRequestType
+{
+ /**
+ * Indicates whether to expand the membership of the group.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $ExpandGroupMembership;
+
+ /**
+ * Contains the query string to filter the mailboxes to be returned.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SearchFilter;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServerTimeZonesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServerTimeZonesType.php
new file mode 100644
index 00000000..7e95fefb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServerTimeZonesType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetServerTimeZonesType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to retrieve time zone definitions from the Exchange
+ * server.
+ *
+ * @package php-ews\Request
+ */
+class GetServerTimeZonesType extends BaseRequestType
+{
+ /**
+ * Contains an array of time zone definition identifiers that specifies the
+ * requested time zone definitions.
+ *
+ * This element is optional.
+ *
+ * If this element is not included in the GetServerTimeZones operation
+ * request, all time zone definitions that are available on the server are
+ * returned in the response.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfTimeZoneIdType
+ */
+ public $Ids;
+
+ /**
+ * Specifies whether the GetServerTimeZones operation returns the complete
+ * definition or only the name and identifier for each time zone.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $ReturnFullTimeZoneData = true;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServiceConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServiceConfigurationType.php
new file mode 100644
index 00000000..b0a5afdc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetServiceConfigurationType.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetServiceConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a GetServiceConfiguration request.
+ *
+ * @package php-ews\Request
+ */
+class GetServiceConfigurationType extends BaseRequestType
+{
+ /**
+ * Identifies who the caller is sending as.
+ *
+ * This element is optional.
+ *
+ * If this element is not present, the authenticated user is assumed to be
+ * the sender. The ActingAs element must be included for requesting sender
+ * hints. An ErrorInvalidArgument error can be returned in a response if the
+ * ActingAs element is missing, does not include a routing type, does not
+ * include an e-mail address, contains an invalid e-mail address, does not
+ * resolve to a user in Active Directory Domain Services (AD DS), or
+ * resolves to multiple users in AD DS.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $ActingAs;
+
+ /**
+ * Contains the requested service configurations.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfServiceConfigurationType
+ */
+ public $RequestedConfiguration;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingFolderType.php
new file mode 100644
index 00000000..a2e1eb97
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingFolderType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetSharingFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get the local folder identifier of a specified shared
+ * folder.
+ *
+ * @package php-ews\Request
+ */
+class GetSharingFolderType extends BaseRequestType
+{
+ /**
+ * Describes the type of data that is shared by a shared folder.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SharingDataType
+ */
+ public $DataType;
+
+ /**
+ * Represents the identifier of the shared folder whose local folder
+ * identifier should be returned.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $SharedFolderId;
+
+ /**
+ * Represents the SMTP e-mail address of the other party in the sharing
+ * relationship.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $SmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingMetadataType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingMetadataType.php
new file mode 100644
index 00000000..62555bb1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetSharingMetadataType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetSharingMetadataType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to get an opaque authentication token that identifies the
+ * sharing invitation.
+ *
+ * @package php-ews\Request
+ */
+class GetSharingMetadataType extends BaseRequestType
+{
+ /**
+ * Represents the identifier of the folder on the server that will be
+ * shared.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $IdOfFolderToShare;
+
+ /**
+ * Represents the SMTP email addresses of one or more entities that will be
+ * granted access to the data in the folder that is identified by the
+ * IdOfFolderToShare element.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSmtpAddressType
+ */
+ public $Recipients;
+
+ /**
+ * Represents the SMTP email address that corresponds to the mailbox that
+ * contains the folder that is identified by the IdOfFolderToShare element.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $SenderSmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetStreamingEventsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetStreamingEventsType.php
new file mode 100644
index 00000000..ffc901e1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetStreamingEventsType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetStreamingEventsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents the operation that is used by clients to request streaming
+ * notifications from the server.
+ *
+ * @package php-ews\Request
+ */
+class GetStreamingEventsType extends BaseRequestType
+{
+ /**
+ * Represents the number of minutes to keep a connection open.
+ *
+ * The value must be between 1 and 30, inclusive.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var integer
+ */
+ public $ConnectionTimeout;
+
+ /**
+ * Represents the identifier for a subscription that is queried for events.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfSubscriptionIdsType
+ */
+ public $SubscriptionId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserAvailabilityRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserAvailabilityRequestType.php
new file mode 100644
index 00000000..da9b7c19
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserAvailabilityRequestType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetUserAvailabilityRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the arguments used to obtain user availability information.
+ *
+ * @package php-ews\Request
+ */
+class GetUserAvailabilityRequestType extends BaseRequestType
+{
+ /**
+ * Specifies the type of free/busy information returned in the response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FreeBusyViewOptionsType
+ */
+ public $FreeBusyViewOptions;
+
+ /**
+ * Contains a list of mailboxes to query for availability information.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfMailboxData
+ */
+ public $MailboxDataArray;
+
+ /**
+ * Contains the options for obtaining meeting suggestion information.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SuggestionsViewOptionsType
+ */
+ public $SuggestionsViewOptions;
+
+ /**
+ * Contains elements that identify time zone information.
+ *
+ * This element also contains information about the transition between
+ * standard time and daylight saving time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SerializableTimeZone
+ */
+ public $TimeZone;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserConfigurationType.php
new file mode 100644
index 00000000..061054e0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserConfigurationType.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetUserConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to get a user configuration object.
+ *
+ * @package php-ews\Request
+ */
+class GetUserConfigurationType extends BaseRequestType
+{
+ /**
+ * Represents the name of a user configuration object.
+ *
+ * This element must be present in a GetUserConfiguration request.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationNameType
+ */
+ public $UserConfigurationName;
+
+ /**
+ * Specifies the user configuration property types to return.
+ *
+ * This element must be present in a GetUserConfiguration request.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\UserConfigurationPropertyType
+ */
+ public $UserConfigurationProperties;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserOofSettingsRequest.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserOofSettingsRequest.php
new file mode 100644
index 00000000..6b9c5c55
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserOofSettingsRequest.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetUserOofSettingsRequest.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the arguments used to get a mailbox user's Out of Office (OOF)
+ * settings.
+ *
+ * @package php-ews\Request
+ */
+class GetUserOofSettingsRequest extends BaseRequestType
+{
+ /**
+ * Identifies the mailbox user for the request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserPhotoType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserPhotoType.php
new file mode 100644
index 00000000..d4dffd86
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserPhotoType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetUserPhotoType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the request to get a user’s photo.
+ *
+ * @package php-ews\Request
+ */
+class GetUserPhotoType extends BaseRequestType
+{
+ /**
+ * Identifies the email address of the user whose photo is requested.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Email;
+
+ /**
+ * Contains the requested photo size.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\UserPhotoSizeType
+ */
+ public $SizeRequested;
+
+ /**
+ * Specifies the type of a user photo.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\UserPhotoTypeType
+ */
+ public $TypeRequested;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserRetentionPolicyTagsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserRetentionPolicyTagsType.php
new file mode 100644
index 00000000..c2c6edc4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/GetUserRetentionPolicyTagsType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\GetUserRetentionPolicyTagsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the request to get the retention tags associated with the user.
+ *
+ * @package php-ews\Request
+ */
+class GetUserRetentionPolicyTagsType extends BaseRequestType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/InstallAppType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/InstallAppType.php
new file mode 100644
index 00000000..0a7217bc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/InstallAppType.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\InstallAppType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the request to install an app.
+ *
+ * @package php-ews\Request
+ */
+class InstallAppType extends BaseRequestType
+{
+ /**
+ * Contains the base64-encoded app manifest file.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $Manifest;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ManifestUrl;
+
+ /**
+ * The asset id of the addin in the marketplace
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ public $MarketplaceAssetId;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $MarketplaceContentMarket;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ *
+ * @todo Update once documentation exists.
+ */
+ public $SendWelcomeEmail;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAllItemsAsRead.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAllItemsAsRead.php
new file mode 100644
index 00000000..135694dd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAllItemsAsRead.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\MarkAllItemsAsRead.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to mark all the items in a folder as read.
+ *
+ * @package php-ews\Request
+ */
+class MarkAllItemsAsRead extends BaseRequestType
+{
+ /**
+ * Contains an array of folder identifiers that are used to identify folders
+ * mark items within.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FolderIds;
+
+ /**
+ * Indicates the read state to set on items in a folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $ReadFlag;
+
+ /**
+ * Indicates whether read receipts should be suppressed.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $SuppressReadReceipts;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAsJunkType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAsJunkType.php
new file mode 100644
index 00000000..979517cd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MarkAsJunkType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\MarkAsJunkType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the request to move an item to the junk mail folder and to add the
+ * sender to the blocked sender list.
+ *
+ * @package php-ews\Request
+ */
+class MarkAsJunkType extends BaseRequestType
+{
+ /**
+ * Whether or not to add the sender to the blocked sender list.
+ *
+ * If false, and the user is already on the blocked sender list, they will
+ * be removed.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsJunk;
+
+ /**
+ * Contains the unique identities of items to be marked as junk.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ItemIds;
+
+ /**
+ * Whether or not to move the item to the default junk mail folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $MoveItem;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveFolderType.php
new file mode 100644
index 00000000..a9f3da47
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveFolderType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\MoveFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to move a folder in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class MoveFolderType extends BaseMoveCopyFolderType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveItemType.php
new file mode 100644
index 00000000..82ce59ec
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/MoveItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\MoveItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to move an item in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class MoveItemType extends BaseMoveCopyItemType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PerformReminderActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PerformReminderActionType.php
new file mode 100644
index 00000000..33d56ee0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PerformReminderActionType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\PerformReminderActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to perform a reminder action.
+ *
+ * @package php-ews\Request
+ */
+class PerformReminderActionType extends BaseRequestType
+{
+ /**
+ * Specifies the actions for reminder items.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfReminderItemActionType
+ */
+ public $ReminderItemActions;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PlayOnPhoneType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PlayOnPhoneType.php
new file mode 100644
index 00000000..4dea5cb2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/PlayOnPhoneType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\PlayOnPhoneType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to read an item on a phone.
+ *
+ * @package php-ews\Request
+ */
+class PlayOnPhoneType extends BaseRequestType
+{
+ /**
+ * Represents the dial string of the phone number that is called to play an
+ * item by phone.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $DialString;
+
+ /**
+ * Represents the identifier of an item to play on a phone.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RefreshSharingFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RefreshSharingFolderType.php
new file mode 100644
index 00000000..32829590
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RefreshSharingFolderType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\RefreshSharingFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to refresh the specified local folder.
+ *
+ * @package php-ews\Request
+ */
+class RefreshSharingFolderType extends BaseRequestType
+{
+ /**
+ * Represents the identifier of the local folder in a sharing relationship.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $SharingFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveContactFromImListType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveContactFromImListType.php
new file mode 100644
index 00000000..2beb6a2a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveContactFromImListType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\RemoveContactFromImListType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to remove an instant messaging contact from all instant
+ * messaging groups.
+ *
+ * @package php-ews\Request
+ */
+class RemoveContactFromImListType extends BaseRequestType
+{
+ /**
+ * Uniquely identifies a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ContactId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDelegateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDelegateType.php
new file mode 100755
index 00000000..9f7273eb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDelegateType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\RemoveDelegateType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to remove delegates from a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class RemoveDelegateType extends BaseDelegateType
+{
+ /**
+ * Contains an array of delegate users to remove from a principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfUserIdType
+ */
+ public $UserIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDistributionGroupFromImListType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDistributionGroupFromImListType.php
new file mode 100644
index 00000000..74d2b014
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveDistributionGroupFromImListType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\RemoveDistributionGroupFromImListType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to remove a specific instant messaging distribution list
+ * group.
+ *
+ * @package php-ews\Request
+ */
+class RemoveDistributionGroupFromImListType extends BaseRequestType
+{
+ /**
+ * Identifies the distribution group to be removed.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $GroupId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImContactFromGroupType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImContactFromGroupType.php
new file mode 100644
index 00000000..604dc8ab
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImContactFromGroupType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\RemoveImContactFromGroupType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to remove an instant messaging contact from an instant
+ * messaging group.
+ *
+ * @package php-ews\Request
+ */
+class RemoveImContactFromGroupType extends BaseRequestType
+{
+ /**
+ * Identifies the contact to be removed.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ContactId;
+
+ /**
+ * Identifies the group to remove the contact from.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $GroupId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImGroupType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImGroupType.php
new file mode 100644
index 00000000..1e0f0150
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/RemoveImGroupType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\RemoveImGroupType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to remove an instant messaging group.
+ *
+ * @package php-ews\Request
+ */
+class RemoveImGroupType extends BaseRequestType
+{
+ /**
+ * Identifies the group to be removed.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $GroupId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ResolveNamesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ResolveNamesType.php
new file mode 100644
index 00000000..bb86932e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/ResolveNamesType.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\ResolveNamesType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to resolve ambiguous names.
+ *
+ * @package php-ews\Request
+ */
+class ResolveNamesType extends BaseRequestType
+{
+ /**
+ * Identifies the property set returned for contacts.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType
+ */
+ public $ContactDataShape;
+
+ /**
+ * Contains an array of contact folder identifiers that would be searched if
+ * the SearchScope attribute is set to ActiveDirectoryContacts, Contacts, or
+ * ContactsActiveDirectory.
+ *
+ * The ParentFolderIds array can only contain a single contact folder
+ * identifier. If the ParentFolderIds element is not present, the default
+ * Contacts folder is searched.
+ *
+ * The folder identifier can be used for delegate access.
+ *
+ * Active Directory searches are performed by using access control lists
+ * (ACLs). Some users might not have the rights to see some Active Directory
+ * objects.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $ParentFolderIds;
+
+ /**
+ * Describes whether the full contact details for public contacts for a
+ * resolved name are returned in the response.
+ *
+ * This attribute is required for public contacts. This value does not
+ * affect private contacts and private distribution lists, for which ItemId
+ * is always returned.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $ReturnFullContactData;
+
+ /**
+ * Identifies the order and scope for a ResolveNames search.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ResolveNamesSearchScopeType
+ */
+ public $SearchScope;
+
+ /**
+ * Contains the name of a contact or distribution list to resolve.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $UnresolvedEntry;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SearchMailboxesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SearchMailboxesType.php
new file mode 100644
index 00000000..0664cf84
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SearchMailboxesType.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SearchMailboxesType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a SearchMailboxes request.
+ *
+ * @package php-ews\Request
+ */
+class SearchMailboxesType extends BaseRequestType
+{
+ /**
+ * Indicates whether the search result should remove duplicate items.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $Deduplication;
+
+ /**
+ * Contains the language used for the search query.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Language;
+
+ /**
+ * Contains the direction for pagination in the search result.
+ *
+ * The value is Previous or Next.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SearchPageDirectionType
+ */
+ public $PageDirection;
+
+ /**
+ * Specifies the reference for a page item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $PageItemReference;
+
+ /**
+ * Contains the number of items to be returned in a single page for a search
+ * result.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $PageSize;
+
+ /**
+ * Contains the requested property set to be returned in a discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PreviewItemResponseShapeType
+ */
+ public $PreviewItemResponseShape;
+
+ /**
+ * Contains the type of search to perform.
+ *
+ * The type of search can be statistics only or preview only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SearchResultType
+ */
+ public $ResultType;
+
+ /**
+ * Contains a list of mailboxes and associated queries for discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfMailboxQueriesType
+ */
+ public $SearchQueries;
+
+ /**
+ * Contains an item property used for sorting the search result.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\FieldOrderType
+ */
+ public $SortBy;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SendItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SendItemType.php
new file mode 100755
index 00000000..b642082e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SendItemType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SendItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to send an item in the Exchange store.
+ *
+ * @package php-ews\Request
+ */
+class SendItemType extends BaseRequestType
+{
+ /**
+ * Contains the unique identities of items, occurrence items, and recurring
+ * master items that are used to delete, send, get, move, or copy items in
+ * the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ItemIds;
+
+ /**
+ * Identifies the target folder for operations that update, send, and create
+ * items in the Exchange store.
+ *
+ * The save action depends on the value of SaveItemToFolder and whether a
+ * SavedItemFolderId element is present in the request.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $SaveItemToFolder;
+
+ /**
+ * Identifies whether a copy of the sent item is saved.
+ *
+ * The save action depends on the value of SaveItemToFolder and whether a
+ * SavedItemFolderId element is present in the request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $SavedItemFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetHoldOnMailboxesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetHoldOnMailboxesType.php
new file mode 100644
index 00000000..071f0f0e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetHoldOnMailboxesType.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SetHoldOnMailboxesType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to set a mailbox hold policy on mailboxes.
+ *
+ * @package php-ews\Request
+ */
+class SetHoldOnMailboxesType extends BaseRequestType
+{
+ /**
+ * Indicates the type of action for the hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\HoldActionType
+ */
+ public $ActionType;
+
+ /**
+ * Indicates whether the search result should remove duplicate items.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $Deduplication;
+
+ /**
+ * Contains the mailbox hold identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $HoldId;
+
+ /**
+ * Specifies the identity of a hold that preserves the mailbox items.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $InPlaceHoldIdentity;
+
+ /**
+ * Indicates whether to include items that cannot be indexed.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IncludeNonIndexableItems;
+
+ /**
+ * Specifies the amount of time to hold content that matches the mailbox
+ * query.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ public $ItemHoldPeriod;
+
+ /**
+ * Contains the language used for the search query.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Language;
+
+ /**
+ * Contains a list of mailboxes affected by the hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Mailboxes;
+
+ /**
+ * Contains the search query for the hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Query;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetImGroupType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetImGroupType.php
new file mode 100644
index 00000000..71153412
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetImGroupType.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SetImGroupType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to change the display name of an instant messaging group.
+ *
+ * @package php-ews\Request
+ */
+class SetImGroupType extends BaseRequestType
+{
+ /**
+ * Identifies the instant messaging group to be updated.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $GroupId;
+
+ /**
+ * Contains the updated display name of an instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $NewDisplayName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetUserOofSettingsRequest.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetUserOofSettingsRequest.php
new file mode 100644
index 00000000..ade0952c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SetUserOofSettingsRequest.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SetUserOofSettingsRequest.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the arguments used to set a mailbox user's Out of Office (OOF)
+ * settings.
+ *
+ * @package php-ews\Request
+ */
+class SetUserOofSettingsRequest extends BaseRequestType
+{
+ /**
+ * Identifies the mailbox user for a SetUserOofSettings or
+ * GetUserOofSettings request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+
+ /**
+ * Specifies the OOF settings.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserOofSettings
+ */
+ public $UserOofSettings;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SubscribeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SubscribeType.php
new file mode 100644
index 00000000..4c46c08c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SubscribeType.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SubscribeType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the properties used to create subscriptions.
+ *
+ * @package php-ews\Request
+ */
+class SubscribeType extends BaseRequestType
+{
+ /**
+ * Represents a subscription to a pull-based event notification.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PullSubscriptionRequestType
+ */
+ public $PullSubscriptionRequest;
+
+ /**
+ * Represents a subscription to a push-based event notification.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PushSubscriptionRequestType
+ */
+ public $PushSubscriptionRequest;
+
+ /**
+ * Represents a subscription to a streaming event notification.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\StreamingSubscriptionRequest
+ */
+ public $StreamingSubscriptionRequest;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderHierarchyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderHierarchyType.php
new file mode 100644
index 00000000..72a595ae
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderHierarchyType.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SyncFolderHierarchyType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to synchronize a folder hierarchy on a client.
+ *
+ * @package php-ews\Request
+ */
+class SyncFolderHierarchyType extends BaseRequestType
+{
+ /**
+ * Identifies the folder properties to include in a SyncFolderHierarchy
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderResponseShapeType
+ */
+ public $FolderShape;
+
+ /**
+ * Represents the folder that contains the items to synchronize.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $SyncFolderId;
+
+ /**
+ * Contains a base64-encoded form of the synchronization data that is
+ * updated after each successful request.
+ *
+ * This is used to identify the synchronization state.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SyncState;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderItemsType.php
new file mode 100644
index 00000000..ccf088d7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/SyncFolderItemsType.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\SyncFolderItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to synchronize items in an Exchange store folder.
+ *
+ * @package php-ews\Request
+ */
+class SyncFolderItemsType extends BaseRequestType
+{
+ /**
+ * Identifies items to skip during synchronization.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfBaseItemIdsType
+ */
+ public $Ignore;
+
+ /**
+ * Identifies the item properties and content to include in a
+ * SyncFolderItems response.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemResponseShapeType
+ */
+ public $ItemShape;
+
+ /**
+ * Describes the maximum number of changes that can be returned in a
+ * synchronization response.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MaxChangesReturned;
+
+ /**
+ * Represents the folder that contains the items to synchronize.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $SyncFolderId;
+
+ /**
+ * Specifies whether just items or items and folder associated information
+ * are returned in a synchronization response.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SyncFolderItemsScopeType
+ */
+ public $SyncScope;
+
+ /**
+ * Contains a base64-encoded form of the synchronization data that is
+ * updated after each successful request.
+ *
+ * This is used to identify the synchronization state.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SyncState;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UninstallAppType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UninstallAppType.php
new file mode 100644
index 00000000..1384f27e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UninstallAppType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UninstallAppType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to uninstall an app by its identifier.
+ *
+ * @package php-ews\Request
+ */
+class UninstallAppType extends BaseRequestType
+{
+ /**
+ * Specifies the identifier of an app.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ID;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UnsubscribeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UnsubscribeType.php
new file mode 100644
index 00000000..d75ab3f3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UnsubscribeType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UnsubscribeType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines the properties used to unsubscribe from a subscription.
+ *
+ * @package php-ews\Request
+ */
+class UnsubscribeType extends BaseRequestType
+{
+ /**
+ * Represents the identifier for a subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SubscriptionId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateDelegateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateDelegateType.php
new file mode 100755
index 00000000..e6489af3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateDelegateType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UpdateDelegateType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to update delegates in a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class UpdateDelegateType extends BaseDelegateType
+{
+ /**
+ * Contains an array of DelegateUser elements that identify the delegates
+ * and the updates to apply to the delegates.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfDelegateUserType
+ */
+ public $DelegateUsers;
+
+ /**
+ * Defines how meeting requests are handled between the delegate and the
+ * principal.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DeliverMeetingRequestsType
+ */
+ public $DeliverMeetingRequests;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateFolderType.php
new file mode 100644
index 00000000..fc466ee0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateFolderType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UpdateFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents the operation that is used to update properties for a specified
+ * folder.
+ *
+ * @package php-ews\Request
+ */
+class UpdateFolderType extends BaseRequestType
+{
+ /**
+ * Contains a collection of changes for a specified folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFolderChangesType
+ */
+ public $FolderChanges;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateInboxRulesRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateInboxRulesRequestType.php
new file mode 100755
index 00000000..aad7509d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateInboxRulesRequestType.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UpdateInboxRulesRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to update the Inbox rules in a mailbox in the server store.
+ *
+ * @package php-ews\Request
+ */
+class UpdateInboxRulesRequestType extends BaseRequestType
+{
+ /**
+ * Represents the SMTP address of the user whose Inbox rules are to be
+ * created, modified, or deleted.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $MailboxSmtpAddress;
+
+ /**
+ * Contains an array of rule operations that can be performed on an Inbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRuleOperationsType
+ */
+ public $Operations;
+
+ /**
+ * Indicates whether to remove the Microsoft Outlook rule blob.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $RemoveOutlookRuleBlob;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateItemType.php
new file mode 100644
index 00000000..9f7fa07c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateItemType.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UpdateItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Defines a request to update an item in a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class UpdateItemType extends BaseRequestType
+{
+ /**
+ * Identifies the type of conflict resolution to try during an update.
+ *
+ * The default value is AutoResolve.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConflictResolutionType
+ */
+ public $ConflictResolution;
+
+ /**
+ * Contains an array of ItemChange elements that identify items and the
+ * updates to apply to the items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemChangesType
+ */
+ public $ItemChanges;
+
+ /**
+ * Describes how the item will be handled after it is updated.
+ *
+ * he MessageDisposition attribute is required for message items, including
+ * meeting messages such as meeting cancellations, meeting requests, and
+ * meeting responses.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MessageDispositionType
+ */
+ public $MessageDisposition;
+
+ /**
+ * Identifies the target folder for operations that update, send, and create
+ * items in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $SavedItemFolderId;
+
+ /**
+ * Describes how meeting updates are communicated after a calendar item is
+ * updated.
+ *
+ * This attribute is required for calendar items and calendar item
+ * occurrences.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarItemUpdateOperationType
+ */
+ public $SendMeetingInvitationsOrCancellations;
+
+ /**
+ * Indicates whether read receipts for the updated item should be
+ * suppressed.
+ *
+ * A value of true indicates that read receipts should be suppressed. A
+ * value of false indicates that the read receipts will be sent to the
+ * sender.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var boolean
+ */
+ public $SuppressReadReceipts;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateUserConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateUserConfigurationType.php
new file mode 100644
index 00000000..c578d475
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UpdateUserConfigurationType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UpdateUserConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to update a user configuration object.
+ *
+ * @package php-ews\Request
+ */
+class UpdateUserConfigurationType extends BaseRequestType
+{
+ /**
+ * Defines a single user configuration object.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationType
+ */
+ public $UserConfiguration;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UploadItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UploadItemsType.php
new file mode 100644
index 00000000..7f646f6c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Request/UploadItemsType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Request\UploadItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\Request;
+
+/**
+ * Represents a request to upload items into a mailbox.
+ *
+ * @package php-ews\Request
+ */
+class UploadItemsType extends BaseRequestType
+{
+ /**
+ * Contains an array of items to upload into a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfUploadItemsType
+ */
+ public $Items;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response.php
new file mode 100644
index 00000000..22d882f4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response.
+ */
+
+namespace jamesiarmes\PhpEws;
+
+/**
+ * Base class for Exchange Web Service responses.
+ *
+ * @package php-ews\Response
+ */
+abstract class Response extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDelegateResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDelegateResponseMessageType.php
new file mode 100644
index 00000000..b43bb6cd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDelegateResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\AddDelegateResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Contains the status and result of an AddDelegate Operation request.
+ *
+ * @package php-ews\Response
+ */
+class AddDelegateResponseMessageType extends BaseDelegateResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDistributionGroupToImListResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDistributionGroupToImListResponseMessageType.php
new file mode 100644
index 00000000..f4f0cb5f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddDistributionGroupToImListResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\AddDistributionGroupToImListResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a AddDistributionGroupToImList request.
+ *
+ * @package php-ews\Response
+ */
+class AddDistributionGroupToImListResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents an instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ImGroupType
+ */
+ public $ImGroup;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImContactToGroupResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImContactToGroupResponseMessageType.php
new file mode 100644
index 00000000..7a1acbe1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImContactToGroupResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\AddImContactToGroupResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an AddImContactToGroup request.
+ *
+ * @package php-ews\Response
+ */
+class AddImContactToGroupResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImGroupResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImGroupResponseMessageType.php
new file mode 100644
index 00000000..38852cfb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddImGroupResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\AddImGroupResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an AddImGroup request.
+ *
+ * @package php-ews\Response
+ */
+class AddImGroupResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents the new instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ImGroupType
+ */
+ public $ImGroup;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewImContactToGroupResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewImContactToGroupResponseMessageType.php
new file mode 100644
index 00000000..1d15c057
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewImContactToGroupResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\AddNewImContactToGroupResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an AddNewImContactToGroup request.
+ *
+ * @package php-ews\Response
+ */
+class AddNewImContactToGroupResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies a set of persona data.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaType
+ */
+ public $Persona;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewTelUriContactToGroupResponse.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewTelUriContactToGroupResponse.php
new file mode 100644
index 00000000..58bdf82d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AddNewTelUriContactToGroupResponse.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\AddNewTelUriContactToGroupResponse.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the result data for a AddNewTelUriContactToGroup request.
+ *
+ * @package php-ews\Response
+ */
+class AddNewTelUriContactToGroupResponse extends ResponseMessageType
+{
+ /**
+ * Specifies a set of persona data returned by a
+ * AddNewTelUriContactToGroupType request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaType
+ */
+ public $Persona;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseMessageType.php
new file mode 100644
index 00000000..3a6c00f8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseMessageType.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ApplyConversationActionResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and results of an ApplyConversationAction operation
+ * request.
+ *
+ * @package php-ews\Response
+ *
+ * @todo Is this class needed?
+ */
+class ApplyConversationActionResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseType.php
new file mode 100644
index 00000000..e808747c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ApplyConversationActionResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ApplyConversationActionResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an ApplyConversationAction operation request.
+ *
+ * @package php-ews\Response
+ */
+class ApplyConversationActionResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ArchiveItemResponse.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ArchiveItemResponse.php
new file mode 100644
index 00000000..fb2c61b7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ArchiveItemResponse.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ArchiveItemResponse.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to an ArchiveItem request.
+ *
+ * @package php-ews\Response
+ */
+class ArchiveItemResponse extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AttachmentInfoResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AttachmentInfoResponseMessageType.php
new file mode 100644
index 00000000..38712f1b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/AttachmentInfoResponseMessageType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\AttachmentInfoResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single CreateAttachment operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class AttachmentInfoResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the items or files that are attached to an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfAttachmentsType
+ */
+ public $Attachments;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseDelegateResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseDelegateResponseMessageType.php
new file mode 100644
index 00000000..c822e859
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseDelegateResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\BaseDelegateResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Base class for delegate response messages.
+ *
+ * @package php-ews\Response
+ */
+abstract class BaseDelegateResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the response messages for an Exchange Web Services delegate
+ * management request.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfDelegateUserResponseMessageType
+ */
+ public $ResponseMessages;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseResponseMessageType.php
new file mode 100644
index 00000000..0b2360b1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/BaseResponseMessageType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\BaseResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+use \jamesiarmes\PhpEws\Response;
+
+/**
+ * Base class for responses.
+ *
+ * @package php-ews\Response
+ */
+class BaseResponseMessageType extends Response
+{
+ /**
+ * Contains the response messages for an Exchange Web Services request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfResponseMessagesType
+ */
+ public $ResponseMessages;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseMessageType.php
new file mode 100644
index 00000000..3e496ad8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ConvertIdResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a ConvertId operation request.
+ *
+ * @package php-ews\Response
+ */
+class ConvertIdResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Describes a converted identifier in the response.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\AlternateIdType
+ */
+ public $AlternateId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseType.php
new file mode 100644
index 00000000..4ab294d6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ConvertIdResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ConvertIdResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents a response to a ConvertId request.
+ *
+ * @package php-ews\Response
+ */
+class ConvertIdResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyFolderResponseType.php
new file mode 100644
index 00000000..61d11a40
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CopyFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a CopyFolder request.
+ *
+ * @package php-ews\Response
+ */
+class CopyFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyItemResponseType.php
new file mode 100644
index 00000000..3f2f2bfd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CopyItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CopyItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a CopyItem request.
+ *
+ * @package php-ews\Response
+ */
+class CopyItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateAttachmentResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateAttachmentResponseType.php
new file mode 100644
index 00000000..a16b5c72
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateAttachmentResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CreateAttachmentResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a CreateAttachment request.
+ *
+ * @package php-ews\Response
+ */
+class CreateAttachmentResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderPathResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderPathResponseType.php
new file mode 100644
index 00000000..93cf8423
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderPathResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CreateFolderPathResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Response to a request to create a folder path.
+ *
+ * @package php-ews\Response
+ */
+class CreateFolderPathResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderResponseType.php
new file mode 100644
index 00000000..26db0296
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CreateFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a CreateFolder request.
+ *
+ * @package php-ews\Response
+ */
+class CreateFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateItemResponseType.php
new file mode 100644
index 00000000..c115e4fd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CreateItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a CreateItem request.
+ *
+ * @package php-ews\Response
+ */
+class CreateItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateManagedFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateManagedFolderResponseType.php
new file mode 100644
index 00000000..94096c57
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateManagedFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CreateManagedFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a CreateManagedFolder request.
+ *
+ * @package php-ews\Response
+ */
+class CreateManagedFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateUserConfigurationResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateUserConfigurationResponseType.php
new file mode 100644
index 00000000..899a8859
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/CreateUserConfigurationResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\CreateUserConfigurationResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a single CreateUserConfiguration request.
+ *
+ * @package php-ews\Response
+ */
+class CreateUserConfigurationResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DelegateUserResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DelegateUserResponseMessageType.php
new file mode 100644
index 00000000..9af31f49
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DelegateUserResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DelegateUserResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * contains the response message for a single delegate user.
+ *
+ * @package php-ews\Response
+ */
+class DelegateUserResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Identifies a single delegate that is returned in a delegate management
+ * response.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\DelegateUserType
+ */
+ public $DelegateUser;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseMessageType.php
new file mode 100644
index 00000000..c65d05ff
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DeleteAttachmentResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single DeleteAttachment operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class DeleteAttachmentResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Identifies the parent item of a deleted attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RootItemIdType
+ */
+ public $RootItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseType.php
new file mode 100644
index 00000000..b34aae32
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteAttachmentResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DeleteAttachmentResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a DeleteAttachment request.
+ *
+ * @package php-ews\Response
+ */
+class DeleteAttachmentResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteFolderResponseType.php
new file mode 100644
index 00000000..e6a8e488
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DeleteFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a DeleteFolder request.
+ *
+ * @package php-ews\Response
+ */
+class DeleteFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteItemResponseType.php
new file mode 100644
index 00000000..a826ea11
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DeleteItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a single DeleteItem request.
+ *
+ * @package php-ews\Response
+ */
+class DeleteItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteUserConfigurationResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteUserConfigurationResponseType.php
new file mode 100644
index 00000000..36f0a434
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DeleteUserConfigurationResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DeleteUserConfigurationResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a single DeleteUserConfiguration request.
+ *
+ * @package php-ews\Response
+ */
+class DeleteUserConfigurationResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisableAppResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisableAppResponseType.php
new file mode 100644
index 00000000..8bd53116
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisableAppResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DisableAppResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a DisableApp request.
+ *
+ * @package php-ews\Response
+ */
+class DisableAppResponseType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisconnectPhoneCallResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisconnectPhoneCallResponseMessageType.php
new file mode 100644
index 00000000..28ccd0e5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/DisconnectPhoneCallResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\DisconnectPhoneCallResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the status and result of a single DisconnectPhoneCall request.
+ *
+ * @package php-ews\Response
+ */
+class DisconnectPhoneCallResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/EmptyFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/EmptyFolderResponseType.php
new file mode 100644
index 00000000..f6847e92
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/EmptyFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\EmptyFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an EmptyFolder Operation request.
+ *
+ * @package php-ews\Response
+ */
+class EmptyFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseMessageType.php
new file mode 100644
index 00000000..403c6270
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseMessageType.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ExpandDLResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single ExpandDL operation request.
+ *
+ * @package php-ews\Response
+ *
+ * @todo Create a FindResponsePagingAttributes trait.
+ */
+class ExpandDLResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents the next denominator to use for the next request when doing\
+ * fractional paging.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AbsoluteDenominator;
+
+ /**
+ * Contains an array of mailboxes that are contained in a distribution list.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfDLExpansionType
+ */
+ public $DLExpansion;
+
+ /**
+ * Indicates that additional paging is not needed.
+ *
+ * This attribute will be true if the current results contain the last item
+ * in the query.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludesLastItemInRange;
+
+ /**
+ * Represents the next index that should be used for the next request when
+ * an indexed paging view is used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $IndexedPagingOffset;
+
+ /**
+ * Represents the new numerator value to use for the next request when
+ * fraction page views are used.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumeratorOffset;
+
+ /**
+ * Represents the total number of items that pass the restriction.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $TotalItemsInView;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseType.php
new file mode 100644
index 00000000..531b4e66
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExpandDLResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ExpandDLResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a request to expand a distribution list.
+ *
+ * @package php-ews\Response
+ */
+class ExpandDLResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseMessageType.php
new file mode 100644
index 00000000..b74d9262
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseMessageType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ExportItemsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and results of a request to export a single mailbox
+ * item.
+ *
+ * @package php-ews\Response
+ */
+class ExportItemsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the item identifier of an exported item.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Contains the contents of an exported item.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $Data;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseType.php
new file mode 100644
index 00000000..77023ed3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ExportItemsResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ExportItemsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents a response to a single ExportItems request.
+ *
+ * @package php-ews\Response
+ */
+class ExportItemsResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindConversationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindConversationResponseMessageType.php
new file mode 100644
index 00000000..ad25e0d5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindConversationResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindConversationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a FindConversation Operation request.
+ *
+ * @package php-ews\Response
+ */
+class FindConversationResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains an array of conversations.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfConversationsType
+ */
+ public $Conversations;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseMessageType.php
new file mode 100644
index 00000000..84327715
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindFolderResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single FindFolder operation request.
+ *
+ * @package php-ews\Response
+ */
+class FindFolderResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the results from a search of a single root folder during a
+ * FindFolder operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FindFolderParentType
+ */
+ public $RootFolder;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseType.php
new file mode 100644
index 00000000..273653ad
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a FindFolder request.
+ *
+ * @package php-ews\Response
+ */
+class FindFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseMessageType.php
new file mode 100644
index 00000000..190bb4bb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindItemResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single FindItem operation request.
+ *
+ * @package php-ews\Response
+ */
+class FindItemResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the results from a search of a single root folder during a
+ * FindItem operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FindItemParentType
+ */
+ public $RootFolder;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseType.php
new file mode 100644
index 00000000..e828c977
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a FindItem request.
+ *
+ * @package php-ews\Response
+ */
+class FindItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseMessageType.php
new file mode 100644
index 00000000..1d150e53
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseMessageType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindMailboxStatisticsByKeywordsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the response message for a FindMailboxStatisticsByKeywords
+ * request.
+ *
+ * @package php-ews\Type
+ */
+class FindMailboxStatisticsByKeywordsResponseMessageType extends
+ ResponseMessageType
+{
+ /**
+ * Specifies the result of a mailbox search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailboxStatisticsSearchResultType
+ */
+ public $MailboxStatisticsSearchResult;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseType.php
new file mode 100644
index 00000000..93bff951
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMailboxStatisticsByKeywordsResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindMailboxStatisticsByKeywordsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a FindMailboxStatisticsByKeywords request.
+ *
+ * @package php-ews\Response
+ */
+class FindMailboxStatisticsByKeywordsResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMessageTrackingReportResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMessageTrackingReportResponseMessageType.php
new file mode 100644
index 00000000..8bf2452a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindMessageTrackingReportResponseMessageType.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindMessageTrackingReportResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single FindMessageTrackingReport
+ * Operation request.
+ *
+ * @package php-ews\Response
+ */
+class FindMessageTrackingReportResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains information that will be used to produce various statistical
+ * reports for the tracking feature in a DataCenter.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Diagnostics;
+
+ /**
+ * Contains a property bag to store errors that are returned through the Web
+ * service.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfArraysOfTrackingPropertiesType
+ */
+ public $Errors;
+
+ /**
+ * Contains the scope of the search that was performed to get the search results.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $ExecutedSearchScope;
+
+ /**
+ * Contains and array of messages that match the search requirements.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFindMessageTrackingSearchResultType
+ */
+ public $MessageTrackingSearchResults;
+
+ /**
+ * Contains a list of one or more tracking properties.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType
+ */
+ public $Properties;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindPeopleResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindPeopleResponseMessageType.php
new file mode 100644
index 00000000..ecce5677
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FindPeopleResponseMessageType.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FindPeopleResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a FindPeople request.
+ *
+ * @package php-ews\Response
+ */
+class FindPeopleResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $FirstLoadedRowIndex;
+
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $FirstMatchingRowIndex;
+
+ /**
+ * Specifies an array of persona data.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPeopleType
+ */
+ public $People;
+
+ /**
+ * Specifies the total number of personas stored on a server that are
+ * returned by a FindPeople request.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $TotalNumberOfPeopleInView;
+
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $TransactionId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FolderInfoResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FolderInfoResponseMessageType.php
new file mode 100644
index 00000000..8b299355
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/FolderInfoResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\FolderInfoResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single CopyFolder operation request.
+ *
+ * @package php-ews\Response
+ */
+class FolderInfoResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains an array of copied folders.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFoldersType
+ */
+ public $Folders;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppManifestsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppManifestsResponseType.php
new file mode 100644
index 00000000..5c4ddf04
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppManifestsResponseType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetAppManifestsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response for a GetAppManifests operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetAppManifestsResponseType extends ResponseMessageType
+{
+ /**
+ * Contains information about all the XML manifest files for apps installed
+ * in a mailbox.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfAppsType
+ */
+ public $Apps;
+
+ /**
+ * Contains a collection of base64-encoded app manifests that are installed
+ * for the email account.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfAppManifestsType
+ */
+ public $Manifests;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppMarketplaceUrlResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppMarketplaceUrlResponseMessageType.php
new file mode 100644
index 00000000..a54339c9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAppMarketplaceUrlResponseMessageType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetAppMarketplaceUrlResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetAppMarketplaceUrl request.
+ *
+ * @package php-ews\Response
+ */
+class GetAppMarketplaceUrlResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies the URL for the app marketplace.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ public $AppMarketplaceUrl;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ConnectorsManagementUrl;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAttachmentResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAttachmentResponseType.php
new file mode 100644
index 00000000..bad8d109
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetAttachmentResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetAttachmentResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetAttachment request.
+ *
+ * @package php-ews\Response
+ */
+class GetAttachmentResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseMessageType.php
new file mode 100644
index 00000000..6a8c9779
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetClientAccessTokenResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response message for a GetClientAccessToken request.
+ *
+ * @package php-ews\Response
+ */
+class GetClientAccessTokenResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies a client access token.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ClientAccessTokenType
+ */
+ public $Token;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseType.php
new file mode 100644
index 00000000..ee79d950
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetClientAccessTokenResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetClientAccessTokenResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetClientAccessToken operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetClientAccessTokenResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseMessageType.php
new file mode 100644
index 00000000..1ece31b2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetConversationItemsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response message for a GetConversationItems request.
+ *
+ * @package php-ews\Response
+ */
+class GetConversationItemsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents a single conversation.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConversationResponseType
+ */
+ public $Conversation;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseType.php
new file mode 100644
index 00000000..0cd81875
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetConversationItemsResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetConversationItemsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetConversationItems request.
+ *
+ * @package php-ews\Response
+ */
+class GetConversationItemsResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDelegateResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDelegateResponseMessageType.php
new file mode 100644
index 00000000..6f3cfbdc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDelegateResponseMessageType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetDelegateResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a GetDelegate operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetDelegateResponseMessageType extends BaseDelegateResponseMessageType
+{
+ /**
+ * Defines how meeting requests are handled between the delegate and the
+ * principal.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DeliverMeetingRequestsType
+ */
+ public $DeliverMeetingRequests;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDiscoverySearchConfigurationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDiscoverySearchConfigurationResponseMessageType.php
new file mode 100644
index 00000000..12ddecc2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetDiscoverySearchConfigurationResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetDiscoverySearchConfigurationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetDiscoverySearchConfiguration request.
+ *
+ * @package php-ews\Response
+ */
+class GetDiscoverySearchConfigurationResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies an array of discovery search configurations.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfDiscoverySearchConfigurationType
+ */
+ public $DiscoverySearchConfigurations;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseMessageType.php
new file mode 100644
index 00000000..2ef59b0d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetEventsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single GetEvents operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetEventsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains information about the subscription and the events that have
+ * occurred since the last notification.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\NotificationType
+ */
+ public $Notification;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseType.php
new file mode 100644
index 00000000..a5b8c334
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetEventsResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetEventsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents a response to a GetEvents request.
+ *
+ * @package php-ews\Response
+ */
+class GetEventsResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetFolderResponseType.php
new file mode 100644
index 00000000..61476357
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetFolder request.
+ *
+ * @package php-ews\Response
+ */
+class GetFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetHoldOnMailboxesResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetHoldOnMailboxesResponseMessageType.php
new file mode 100644
index 00000000..870b36b1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetHoldOnMailboxesResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetHoldOnMailboxesResponse.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to get the hold status for a mailbox.
+ *
+ * @package php-ews\Response
+ */
+class GetHoldOnMailboxesResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the result of the GetHoldOnMailboxes request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailboxHoldResultType
+ */
+ public $MailboxHoldResult;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemListResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemListResponseMessageType.php
new file mode 100644
index 00000000..bbf71d29
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemListResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetImItemListResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetImItemList request.
+ *
+ * @package php-ews\Response
+ */
+class GetImItemListResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains a list of instant messaging groups and instant messaging
+ * contacts.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ImItemListType
+ */
+ public $ImItemList;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemsResponse.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemsResponse.php
new file mode 100644
index 00000000..d54cb8fe
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetImItemsResponse.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetImItemsResponse.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetImItems request.
+ *
+ * @package php-ews\Response
+ */
+class GetImItemsResponse extends ResponseMessageType
+{
+ /**
+ * Contains a list of instant messaging groups and instant messaging
+ * contacts.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ImItemListType
+ */
+ public $ImItemList;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetInboxRulesResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetInboxRulesResponseType.php
new file mode 100644
index 00000000..465885e3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetInboxRulesResponseType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetInboxRulesResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetInboxRules operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetInboxRulesResponseType extends ResponseMessageType
+{
+ /**
+ * Represents an array of the rules in the user's mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRulesType
+ */
+ public $InboxRules;
+
+ /**
+ * Indicates whether a Microsoft Outlook rule blob exists in the user's
+ * mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $OutlookRuleBlobExists;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetItemResponseType.php
new file mode 100644
index 00000000..faa7acb4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetItem request.
+ *
+ * @package php-ews\Response
+ */
+class GetItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMailTipsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMailTipsResponseMessageType.php
new file mode 100644
index 00000000..053c0efd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMailTipsResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetMailTipsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the response message for a GetMailTips Operation.
+ *
+ * @package php-ews\Response
+ */
+class GetMailTipsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents a list of mail tips response messages.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfMailTipsResponseMessageType
+ */
+ public $ResponseMessages;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMessageTrackingReportResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMessageTrackingReportResponseMessageType.php
new file mode 100644
index 00000000..4c7cdc8e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetMessageTrackingReportResponseMessageType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetMessageTrackingReportResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the response for the GetMessageTrackingReport operation.
+ *
+ * @package php-ews\Response
+ */
+class GetMessageTrackingReportResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains a single message that is returned in a GetMessageTrackingReport
+ * operation.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\MessageTrackingReportType
+ */
+ public $MessageTrackingReport;
+
+ /**
+ * Provides timing and performance information that is used for reporting in
+ * a DataCenter.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Diagnostics;
+
+ /**
+ * Contains a property bag to store errors that are returned through the Web
+ * service.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfArraysOfTrackingPropertiesType
+ */
+ public $Errors;
+
+ /**
+ * Contains a list of one or more tracking properties.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType
+ */
+ public $Properties;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemDetailsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemDetailsResponseMessageType.php
new file mode 100644
index 00000000..99bb4bc9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemDetailsResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetNonIndexableItemDetailsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetNonIndexableItemDetails request.
+ *
+ * @package php-ews\Response
+ */
+class GetNonIndexableItemDetailsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies the results of the GetNonIndexableItemDetails request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\NonIndexableItemDetailResultType
+ */
+ public $NonIndexableItemDetailsResult;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemStatisticsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemStatisticsResponseMessageType.php
new file mode 100644
index 00000000..d4c4f7df
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetNonIndexableItemStatisticsResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetNonIndexableItemStatisticsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetNonIndexableItemStatistics request.
+ *
+ * @package php-ews\Response
+ */
+class GetNonIndexableItemStatisticsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains an array of statistics for items that could not be indexed.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfNonIndexableItemStatisticsType
+ */
+ public $NonIndexableItemStatistics;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPasswordExpirationDateResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPasswordExpirationDateResponseMessageType.php
new file mode 100644
index 00000000..0d030043
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPasswordExpirationDateResponseMessageType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetPasswordExpirationDateResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetPasswordExpirationDate operation operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class GetPasswordExpirationDateResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Provides the password expiration date for the email account specified in
+ * the request.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $PasswordExpirationDate;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPersonaResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPersonaResponseMessageType.php
new file mode 100644
index 00000000..5801038c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPersonaResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetPersonaResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response for a GetPersona request.
+ *
+ * @package php-ews\Response
+ */
+class GetPersonaResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies a set of persona data returned by a GetPersona request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaType
+ */
+ public $Persona;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPhoneCallInformationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPhoneCallInformationResponseMessageType.php
new file mode 100644
index 00000000..30bbc836
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetPhoneCallInformationResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetPhoneCallInformationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a single GetPhoneCallInformation request.
+ *
+ * @package php-ews\Response
+ */
+class GetPhoneCallInformationResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies the state information for a phone call.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhoneCallInformationType
+ */
+ public $PhoneCallInformation;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRemindersResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRemindersResponseMessageType.php
new file mode 100644
index 00000000..f6ddc5ae
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRemindersResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetRemindersResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the response to a GetReminders request.
+ *
+ * @package php-ews\Response
+ */
+class GetRemindersResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies the reminders returned in the response.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRemindersType
+ */
+ public $Reminders;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomListsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomListsResponseMessageType.php
new file mode 100644
index 00000000..e832e81b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomListsResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetRoomListsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the response from a GetRoomLists Operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetRoomListsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Provides a list of e-mail addresses and display names that represent
+ * lists of meeting rooms.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $RoomLists;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomsResponseMessageType.php
new file mode 100644
index 00000000..b53c3059
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetRoomsResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetRoomsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the response to a GetRooms operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetRoomsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Provides a list of email addresses and display names that represent
+ * meeting rooms.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRoomsType
+ */
+ public $Rooms;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSearchableMailboxesResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSearchableMailboxesResponseMessageType.php
new file mode 100644
index 00000000..a992cf86
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSearchableMailboxesResponseMessageType.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetSearchableMailboxesResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Contains the response to a GetSearchableMailboxes request.
+ *
+ * @package php-ews\Response
+ */
+class GetSearchableMailboxesResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies an array of mailboxes that failed on search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFailedSearchMailboxesType
+ */
+ public $FailedMailboxes;
+
+ /**
+ * Contains an array of mailboxes.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSearchableMailboxesType
+ */
+ public $SearchableMailboxes;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseMessageType.php
new file mode 100644
index 00000000..b3207e53
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetServerTimeZonesResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single GetServerTimeZones operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class GetServerTimeZonesResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains an array of time zone definitions.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTimeZoneDefinitionType
+ */
+ public $TimeZoneDefinitions;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseType.php
new file mode 100644
index 00000000..254c9608
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServerTimeZonesResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetServerTimeZonesResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetServerTimeZones operation request.
+ *
+ * @package php-ews\Response
+ */
+class GetServerTimeZonesResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServiceConfigurationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServiceConfigurationResponseMessageType.php
new file mode 100644
index 00000000..602eb4f3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetServiceConfigurationResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetServiceConfigurationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a GetServiceConfiguration request.
+ *
+ * @package php-ews\Response
+ */
+class GetServiceConfigurationResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains an array of service configuration response messages.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfServiceConfigurationResponseMessageType
+ */
+ public $ResponseMessages;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingFolderResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingFolderResponseMessageType.php
new file mode 100644
index 00000000..4125fdc3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingFolderResponseMessageType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetSharingFolderResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single GetSharingFolder operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class GetSharingFolderResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents the identifier of the local folder in a sharing relationship.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $SharingFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingMetadataResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingMetadataResponseMessageType.php
new file mode 100644
index 00000000..e29fa70d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetSharingMetadataResponseMessageType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetSharingMetadataResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a request.
+ *
+ * @package php-ews\Response
+ */
+class GetSharingMetadataResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains a collection of data structures that a client can use to
+ * authorize the sharing of its calendar or contact data with other clients.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEncryptedSharedFolderDataType
+ */
+ public $EncryptedSharedFolderDataCollection;
+
+ /**
+ * Represents recipients of the folder sharing request that are invalid.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfInvalidRecipientsType
+ */
+ public $InvalidRecipients;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseMessageType.php
new file mode 100644
index 00000000..7322e710
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseMessageType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetStreamingEventsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single GetStreamingEvents operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class GetStreamingEventsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Provides a text description of the status of a streaming subscription.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConnectionStatusType
+ */
+ public $ConnectionStatus;
+
+ /**
+ * Contains a list of subscription IDs that are invalid.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfSubscriptionIdsType
+ */
+ public $ErrorSubscriptionIds;
+
+ /**
+ * Contains a list of information about the subscription and the events that
+ * have occurred since the last notification.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfNotificationsType
+ */
+ public $Notifications;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseType.php
new file mode 100644
index 00000000..e6002f29
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetStreamingEventsResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetStreamingEventsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents a response to a GetStreamingEvents element request.
+ *
+ * @package php-ews\Response
+ */
+class GetStreamingEventsResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserAvailabilityResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserAvailabilityResponseType.php
new file mode 100644
index 00000000..5fbb1b3e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserAvailabilityResponseType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetUserAvailabilityResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+use \jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the properties that define user availability information or suggested
+ * meeting time information.
+ *
+ * @package php-ews\Response
+ */
+class GetUserAvailabilityResponseType extends Response
+{
+ /**
+ * FContains the requested users' availability information and the response
+ * status.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFreeBusyResponse
+ */
+ public $FreeBusyResponseArray;
+
+ /**
+ * Contains response status information and suggestion data for requested
+ * meeting suggestions.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SuggestionsResponseType
+ */
+ public $SuggestionsResponse;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseMessageType.php
new file mode 100644
index 00000000..396fc7ab
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetUserConfigurationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents a response that returns a user configuration object.
+ *
+ * @package php-ews\Response
+ */
+class GetUserConfigurationResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains a single user configuration object.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationType
+ */
+ public $UserConfiguration;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseType.php
new file mode 100644
index 00000000..84214522
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserConfigurationResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetUserConfigurationResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a single GetUserConfiguration request.
+ *
+ * @package php-ews\Response
+ */
+class GetUserConfigurationResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserOofSettingsResponse.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserOofSettingsResponse.php
new file mode 100644
index 00000000..635e570f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserOofSettingsResponse.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetUserOofSettingsResponse.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+use \jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the response message and the Out of Office (OOF) settings for a
+ * user.
+ *
+ * @package php-ews\Response
+ */
+class GetUserOofSettingsResponse extends Response
+{
+ /**
+ * Contains a value that identifies to whom external OOF messages are sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ExternalAudience
+ */
+ public $AllowExternalOof;
+
+ /**
+ * Contains the OOF settings.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserOofSettings
+ */
+ public $OofSettings;
+
+ /**
+ * Provides descriptive information about the response status.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType
+ */
+ public $ResponseMessage;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseMessageType.php
new file mode 100644
index 00000000..c133bae4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseMessageType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetUserPhotoResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetUserPhoto request.
+ *
+ * @package php-ews\Response
+ */
+class GetUserPhotoResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Indicates whether a user’s photo has changed.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $HasChanged;
+
+ /**
+ * Contains the stream of picture data.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $PictureData;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseType.php
new file mode 100644
index 00000000..c182da17
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserPhotoResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetUserPhotoResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetUserPhoto request.
+ *
+ * @package php-ews\Response
+ */
+class GetUserPhotoResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserRetentionPolicyTagsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserRetentionPolicyTagsResponseMessageType.php
new file mode 100644
index 00000000..79ef601a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/GetUserRetentionPolicyTagsResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\GetUserRetentionPolicyTagsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a GetRetentionPolicyTags request.
+ *
+ * @package php-ews\Response
+ */
+class GetUserRetentionPolicyTagsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains a list of retention tags.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRetentionPolicyTagsType
+ */
+ public $RetentionPolicyTags;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/InstallAppResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/InstallAppResponseType.php
new file mode 100644
index 00000000..673eedac
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/InstallAppResponseType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\InstallAppResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to an InstallApp request.
+ *
+ * @package php-ews\Response
+ */
+class InstallAppResponseType extends ResponseMessageType
+{
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var \jamesiarmes\PhpEws\Type\InstalledAppType
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Extension;
+
+ /**
+ * Whether this is the first time the app is being installed.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ */
+ public $WasFirstInstall;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ItemInfoResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ItemInfoResponseMessageType.php
new file mode 100644
index 00000000..c02d89b6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ItemInfoResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ItemInfoResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single item operation request.
+ *
+ * @package php-ews\Response
+ */
+class ItemInfoResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains an array of created items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRealItemsType
+ */
+ public $Items;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MailTipsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MailTipsResponseMessageType.php
new file mode 100644
index 00000000..a3356dca
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MailTipsResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\MailTipsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents mail tips settings.
+ *
+ * @package php-ews\Response
+ */
+class MailTipsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents values for various types of mail tips.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailTips
+ */
+ public $MailTips;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAllItemsAsReadResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAllItemsAsReadResponseType.php
new file mode 100644
index 00000000..44fd5745
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAllItemsAsReadResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\MarkAllItemsAsReadResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a MarkAllItemsAsRead request.
+ *
+ * @package php-ews\Response
+ */
+class MarkAllItemsAsReadResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseMessageType.php
new file mode 100644
index 00000000..d05955d1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\MarkAsJunkResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response message for a MarkAsJunk request.
+ *
+ * @package php-ews\Response
+ */
+class MarkAsJunkResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies the identifier of the item that was moved.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $MovedItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseType.php
new file mode 100644
index 00000000..16ffc477
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MarkAsJunkResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\MarkAsJunkResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a MarkAsJunk request.
+ *
+ * @package php-ews\Response
+ */
+class MarkAsJunkResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveFolderResponseType.php
new file mode 100644
index 00000000..74871138
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\MoveFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a MoveFolder request.
+ *
+ * @package php-ews\Response
+ */
+class MoveFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveItemResponseType.php
new file mode 100644
index 00000000..85e766db
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/MoveItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\MoveItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a MoveItem request.
+ *
+ * @package php-ews\Response
+ */
+class MoveItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PerformReminderActionResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PerformReminderActionResponseMessageType.php
new file mode 100644
index 00000000..fde02253
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PerformReminderActionResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\PerformReminderActionResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a PerformReminderAction request.
+ *
+ * @package php-ews\Response
+ */
+class PerformReminderActionResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies the identifiers of updated reminder items.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemIdsType
+ */
+ public $UpdatedItemIds;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PlayOnPhoneResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PlayOnPhoneResponseMessageType.php
new file mode 100644
index 00000000..ce756191
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/PlayOnPhoneResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\PlayOnPhoneResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a request to play a voice mail over the telephone.
+ *
+ * @package php-ews\Response
+ */
+class PlayOnPhoneResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Specifies the telephone call identifier.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhoneCallIdType
+ */
+ public $PhoneCallId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RefreshSharingFolderResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RefreshSharingFolderResponseMessageType.php
new file mode 100644
index 00000000..7e48a7e0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RefreshSharingFolderResponseMessageType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\RefreshSharingFolderResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single RefreshSharingFolder operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class RefreshSharingFolderResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveContactFromImListResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveContactFromImListResponseMessageType.php
new file mode 100644
index 00000000..51dc7286
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveContactFromImListResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\RemoveContactFromImListResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a RemoveContactFromImList request.
+ *
+ * @package php-ews\Response
+ */
+class RemoveContactFromImListResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDelegateResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDelegateResponseMessageType.php
new file mode 100644
index 00000000..f2a24dfb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDelegateResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\RemoveDelegateResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the status and result of a RemoveDelegate Operation request.
+ *
+ * @package php-ews\Response
+ */
+class RemoveDelegateResponseMessageType extends BaseDelegateResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDistributionGroupFromImListResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDistributionGroupFromImListResponseMessageType.php
new file mode 100644
index 00000000..26bb9afa
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveDistributionGroupFromImListResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\RemoveDistributionGroupFromImListResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a RemoveDistributionGroupFromImList request.
+ *
+ * @package php-ews\Response
+ */
+class RemoveDistributionGroupFromImListResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImContactFromGroupResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImContactFromGroupResponseMessageType.php
new file mode 100644
index 00000000..1d454d90
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImContactFromGroupResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\RemoveImContactFromGroupResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a RemoveImContactFromGroup request.
+ *
+ * @package php-ews\Response
+ */
+class RemoveImContactFromGroupResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImGroupResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImGroupResponseMessageType.php
new file mode 100644
index 00000000..fdfa68bd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/RemoveImGroupResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\RemoveImGroupResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a RemoveImGroup request.
+ *
+ * @package php-ews\Response
+ */
+class RemoveImGroupResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseMessageType.php
new file mode 100644
index 00000000..c92992d3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ResolveNamesResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the status and result of a ResolveNames operation request.
+ *
+ * @package php-ews\Response
+ */
+class ResolveNamesResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains an array of resolutions for an ambiguous name.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfResolutionType
+ */
+ public $ResolutionSet;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseType.php
new file mode 100644
index 00000000..b33a4b23
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResolveNamesResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ResolveNamesResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a ResolveNames request.
+ *
+ * @package php-ews\Response
+ */
+class ResolveNamesResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResponseMessageType.php
new file mode 100644
index 00000000..509b23a5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ResponseMessageType.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+use \jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a request.
+ *
+ * @package php-ews\Response
+ */
+class ResponseMessageType extends Response
+{
+ /**
+ * Currently unused and reserved for future use.
+ *
+ * This element contains a value of 0.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $DescriptiveLinkKey;
+
+ /**
+ * Provides a text description of the status of the response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $MessageText;
+
+ /**
+ * Provides additional error response information.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Determine if we can use SimpleXML or DOMDocument here.
+ */
+ public $MessageXml;
+
+ /**
+ * Describes the status of the response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ResponseClassType
+ */
+ public $ResponseClass;
+
+ /**
+ * Provides an error code that identifies the specific error that the
+ * request encountered.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ResponseCodeType
+ */
+ public $ResponseCode;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseMessageType.php
new file mode 100644
index 00000000..66fc76c2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SearchMailboxesResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response message for a SearchMailboxes request.
+ *
+ * @package php-ews\Response
+ */
+class SearchMailboxesResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the result of the request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchMailboxesResultType
+ */
+ public $SearchMailboxesResult;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseType.php
new file mode 100644
index 00000000..66d968a1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SearchMailboxesResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SearchMailboxesResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to a SearchMailboxes request.
+ *
+ * @package php-ews\Response
+ */
+class SearchMailboxesResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendItemResponseType.php
new file mode 100644
index 00000000..a48fd291
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SendItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a SendItem request.
+ *
+ * @package php-ews\Response
+ */
+class SendItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseMessageType.php
new file mode 100644
index 00000000..891c400a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseMessageType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SendNotificationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single SendNotification operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class SendNotificationResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains information about the subscription and the events that have
+ * occurred since the last notification.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\NotificationType
+ */
+ public $Notification;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseType.php
new file mode 100644
index 00000000..e2ecf776
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SendNotificationResponseType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SendNotificationResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the push notifications that are sent by the computer that is
+ * running Microsoft Exchange Server 2007 to the client application.
+ *
+ * @package php-ews\Response
+ */
+class SendNotificationResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ServiceConfigurationResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ServiceConfigurationResponseMessageType.php
new file mode 100644
index 00000000..47534844
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/ServiceConfigurationResponseMessageType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\ServiceConfigurationResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents service configuration settings.
+ *
+ * @package php-ews\Response
+ */
+class ServiceConfigurationResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains service configuration information for the mail tips service.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailTipsServiceConfiguration
+ */
+ public $MailTipsConfiguration;
+
+ /**
+ * Contains service configuration information for the protection rules
+ * service.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRulesServiceConfiguration
+ */
+ public $ProtectionRulesConfiguration;
+
+ /**
+ * Contains service configuration information for the Unified Messaging
+ * service.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UnifiedMessageServiceConfiguration
+ */
+ public $UnifiedMessagingConfiguration;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetHoldOnMailboxesResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetHoldOnMailboxesResponseMessageType.php
new file mode 100644
index 00000000..c69c9822
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetHoldOnMailboxesResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SetHoldOnMailboxesResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a SetHoldOnMailboxes request.
+ *
+ * @package php-ews\Response
+ */
+class SetHoldOnMailboxesResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the result of the request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\MailboxHoldResultType
+ */
+ public $MailboxHoldResult;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetImGroupResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetImGroupResponseMessageType.php
new file mode 100644
index 00000000..abaca972
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetImGroupResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SetImGroupResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a SetImGroup request.
+ *
+ * @package php-ews\Response
+ */
+class SetImGroupResponseMessageType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetUserOofSettingsResponse.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetUserOofSettingsResponse.php
new file mode 100644
index 00000000..3ac2571f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SetUserOofSettingsResponse.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SetUserOofSettingsResponse.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+use \jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the result of a SetUserOofSettingsRequest message attempt.
+ *
+ * @package php-ews\Response
+ */
+class SetUserOofSettingsResponse extends Response
+{
+ /**
+ * Provides descriptive information about the response status.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType
+ */
+ public $ResponseMessage;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseMessageType.php
new file mode 100644
index 00000000..af3b21f4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseMessageType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SubscribeResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single Subscribe Operation request.
+ *
+ * @package php-ews\Response
+ */
+class SubscribeResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Represents the identifier for a subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SubscriptionId;
+
+ /**
+ * Watermark property
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Determine if we need a WatermarkType.
+ */
+ public $Watermark;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseType.php
new file mode 100644
index 00000000..2d8e0874
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SubscribeResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SubscribeResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a Subscribe request.
+ *
+ * @package php-ews\Response
+ */
+class SubscribeResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseMessageType.php
new file mode 100644
index 00000000..aa153e16
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseMessageType.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SyncFolderHierarchyResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single SyncFolderHierarchy operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class SyncFolderHierarchyResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains a sequence array of change types that represent the types of
+ * differences between the items on the client and the items on the Exchange
+ * server.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderHierarchyChangesType
+ */
+ public $Changes;
+
+ /**
+ * Indicates whether the last item to synchronize has been included in the
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludesLastFolderInRange;
+
+ /**
+ * Contains a base64-encoded form of the synchronization data that is
+ * updated after each successful request.
+ *
+ * This is used to identify the synchronization state.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SyncState;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseType.php
new file mode 100644
index 00000000..e58be528
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderHierarchyResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SyncFolderHierarchyResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a SyncFolderHierarchy request.
+ *
+ * @package php-ews\Response
+ */
+class SyncFolderHierarchyResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseMessageType.php
new file mode 100644
index 00000000..bb49a386
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseMessageType.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SyncFolderItemsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single SyncFolderItems operation
+ * request.
+ *
+ * @package php-ews\Response
+ */
+class SyncFolderItemsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains a sequence array of change types that represent the types of
+ * differences between the items on the client and the items on the Exchange
+ * server.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderItemsChangesType
+ */
+ public $Changes;
+
+ /**
+ * Indicates whether the last item to synchronize has been included in the
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludesLastItemInRange;
+
+ /**
+ * Contains a base64-encoded form of the synchronization data that is
+ * updated after each successful request.
+ *
+ * This is used to identify the synchronization state.
+ * .
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SyncState;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseType.php
new file mode 100644
index 00000000..b6645d39
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/SyncFolderItemsResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\SyncFolderItemsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a SyncFolderItems request.
+ *
+ * @package php-ews\Response
+ */
+class SyncFolderItemsResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UninstallAppResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UninstallAppResponseType.php
new file mode 100644
index 00000000..496e128b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UninstallAppResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UninstallAppResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to an UninstallApp request.
+ *
+ * @package php-ews\Response
+ */
+class UninstallAppResponseType extends ResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UnsubscribeResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UnsubscribeResponseType.php
new file mode 100644
index 00000000..9e8c3ba2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UnsubscribeResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UnsubscribeResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an Unsubscribe request.
+ *
+ * @package php-ews\Response
+ */
+class UnsubscribeResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateDelegateResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateDelegateResponseMessageType.php
new file mode 100644
index 00000000..9f44db86
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateDelegateResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UpdateDelegateResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of an UpdateDelegate Operation request.
+ *
+ * @package php-ews\Response
+ */
+class UpdateDelegateResponseMessageType extends BaseDelegateResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateFolderResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateFolderResponseType.php
new file mode 100644
index 00000000..a044d6a1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateFolderResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UpdateFolderResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines the response to an UpdateFolder request.
+ *
+ * @package php-ews\Response
+ */
+class UpdateFolderResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateInboxRulesResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateInboxRulesResponseType.php
new file mode 100644
index 00000000..f7a37a10
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateInboxRulesResponseType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UpdateInboxRulesResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an UpdateInboxRules request.
+ *
+ * @package php-ews\Response
+ */
+class UpdateInboxRulesResponseType extends ResponseMessageType
+{
+ /**
+ * Represents an array of rule validation errors on each rule field that has
+ * an error.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRuleOperationErrorsType
+ */
+ public $RuleOperationErrors;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseMessageType.php
new file mode 100644
index 00000000..c0a67865
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UpdateItemResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents the status and result of a single UpdateItem request.
+ *
+ * @package php-ews\Type
+ */
+class UpdateItemResponseMessageType extends ItemInfoResponseMessageType
+{
+ /**
+ * Contains the number of conflicts in an UpdateItem response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConflictResultsType
+ */
+ public $ConflictResults;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseType.php
new file mode 100644
index 00000000..0d53cb90
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateItemResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UpdateItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to an UpdateItem request.
+ *
+ * @package php-ews\Response
+ */
+class UpdateItemResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateUserConfigurationResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateUserConfigurationResponseType.php
new file mode 100644
index 00000000..3f6dafc5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UpdateUserConfigurationResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UpdateUserConfigurationResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Defines a response to a single UpdateUserConfiguration request.
+ *
+ * @package php-ews\Response
+ */
+class UpdateUserConfigurationResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseMessageType.php
new file mode 100644
index 00000000..7f7bc925
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseMessageType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UploadItemsResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * the status and results of a request to upload a single mailbox item.
+ *
+ * @package php-ews\Response
+ */
+class UploadItemsResponseMessageType extends ResponseMessageType
+{
+ /**
+ * Contains the item identifier of an uploaded item.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseType.php
new file mode 100644
index 00000000..1008cd1a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Response/UploadItemsResponseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Response\UploadItemsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Response;
+
+/**
+ * Represents a response to a single UploadItems request.
+ *
+ * @package php-ews\Response
+ */
+class UploadItemsResponseType extends BaseResponseMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type.php
new file mode 100644
index 00000000..89a25556
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type.
+ */
+
+namespace jamesiarmes\PhpEws;
+
+/**
+ * Base class for Exchange Web Service Types.
+ *
+ * @package php-ews\Type
+ */
+abstract class Type
+{
+ /**
+ * Clones any object properties on a type object when it is cloned. Allows
+ * for a deep clone required when using object to represent data types when
+ * making a SOAP call.
+ */
+ public function __clone()
+ {
+ // Iterate over all properties on the current object.
+ foreach (get_object_vars($this) as $property => $value) {
+ // If the value of the property is an object then clone it.
+ if (is_object($value)) {
+ $this->$property = clone $value;
+ } elseif (is_array($value)) {
+ // The value is an array that may use objects as values. Iterate
+ // over the array and clone any values that are objects into a
+ // new array.
+ // For some reason, if we try to set $this->$property to an
+ // empty array then update it as we go it ends up being empty.
+ // If we use a new array that we then set as the value of
+ // $this->$property all is well.
+ $new_value = array();
+ foreach ($value as $index => $array_value) {
+ $new_value[$index] = (is_object($array_value) ? clone $array_value : $array_value);
+ }
+
+ // Set the property to the new array.
+ $this->$property = $new_value;
+ }
+ }
+ }
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteDateTransitionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteDateTransitionType.php
new file mode 100644
index 00000000..fb06c47b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteDateTransitionType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AbsoluteDateTransitionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a time zone transition that occurs on a specific date and at a
+ * specific time.
+ *
+ * @package php-ews\Type
+ */
+class AbsoluteDateTransitionType extends TransitionType
+{
+ /**
+ * Represents the date and time at which the time zone transition occurs.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $DateTime;
+
+ /**
+ * Specifies the Period or TransitionsGroup that is the target of the time
+ * zone transition.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TransitionTargetType
+ */
+ public $To;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteMonthlyRecurrencePatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteMonthlyRecurrencePatternType.php
new file mode 100644
index 00000000..f11dfc3b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteMonthlyRecurrencePatternType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AbsoluteMonthlyRecurrencePatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a monthly recurrence pattern.
+ *
+ * @package php-ews\Type
+ */
+class AbsoluteMonthlyRecurrencePatternType extends IntervalRecurrencePatternBaseType
+{
+ /**
+ * Describes the day in a month that a recurring item occurs.
+ *
+ * The range of values for this property is 1 to 31. If for a particular
+ * month this value is larger than the number of days in the month, the last
+ * day of the month is assumed for this property.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $DayOfMonth;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteYearlyRecurrencePatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteYearlyRecurrencePatternType.php
new file mode 100644
index 00000000..94d1b0a7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AbsoluteYearlyRecurrencePatternType.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AbsoluteYearlyRecurrencePatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a yearly recurrence pattern.
+ *
+ * @package php-ews\Type
+ */
+class AbsoluteYearlyRecurrencePatternType extends RecurrencePatternBaseType
+{
+ /**
+ * Describes the day in a month on which a recurring item occurs.
+ *
+ * The range of values for this property is 1 to 31. If for a particular
+ * month this value is larger than the number of days in the month, the last
+ * day of the month is assumed for this property.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $DayOfMonth;
+
+ /**
+ * Describes the month in which a yearly recurring item occurs.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MonthNamesType
+ */
+ public $Month;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptItemType.php
new file mode 100644
index 00000000..b0c038dd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AcceptItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an Accept reply to a meeting request.
+ *
+ * @package php-ews\Type
+ */
+class AcceptItemType extends WellKnownResponseObjectType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptSharingInvitationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptSharingInvitationType.php
new file mode 100644
index 00000000..891e0729
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AcceptSharingInvitationType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AcceptSharingInvitationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Used to accept an invitation that allows access to another user’s calendar or
+ * contacts data.
+ *
+ * @package php-ews\Type
+ */
+class AcceptSharingInvitationType extends ReferenceItemResponseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AddressListIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AddressListIdType.php
new file mode 100644
index 00000000..311f6b16
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AddressListIdType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AddressListIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the identifier of an address list.
+ *
+ * @package php-ews\Type
+ */
+class AddressListIdType extends Type
+{
+ /**
+ * A string address list identifier.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Id;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AggregateOnType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AggregateOnType.php
new file mode 100644
index 00000000..15edfafd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AggregateOnType.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AggregateOnType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the property that is used to determine the order of grouped items
+ * for a grouped FindItem result set.
+ *
+ * @package php-ews\Type
+ */
+class AggregateOnType extends Type
+{
+ /**
+ * Indicates the maximum or minimum value of the property identified by the
+ * FieldURI element that is used for ordering the groups of items.
+ *
+ * The following are the possible values:
+ * - Minimum
+ * - Maximum
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\AggregateType
+ */
+ public $Aggregate;
+
+ /**
+ * Identifies extended MAPI properties to get, set, or create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType
+ */
+ public $ExtendedFieldURI;
+
+ /**
+ * Identifies frequently referenced properties by URI.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToUnindexedFieldType
+ */
+ public $FieldURI;
+
+ /**
+ * Identifies individual members of a dictionary.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToIndexedFieldType
+ */
+ public $IndexedFieldURI;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdBaseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdBaseType.php
new file mode 100644
index 00000000..dda8a832
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdBaseType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AlternateIdBaseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for alternate id types.
+ *
+ * @package php-ews\Type
+ */
+abstract class AlternateIdBaseType extends Type
+{
+ /**
+ * Describes the source or destination format in a request.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\IdFormatType
+ */
+ public $Format;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdType.php
new file mode 100644
index 00000000..8a5564a2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternateIdType.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AlternateIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes an identifier to convert in a request and the results of a
+ * converted identifier in the response.
+ *
+ * @package php-ews\Type
+ */
+class AlternateIdType extends AlternateIdBaseType
+{
+ /**
+ * Describes the source identifier in a ConvertId Operation request and
+ * describes the destination identifier in a ConvertId Operation response.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $Id;
+
+ /**
+ * Indicates whether the identifier represents an archived item or folder.
+ *
+ * A value of true indicates that the identifier represents an archived item
+ * or folder. This attribute is optional.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $IsArchive;
+
+ /**
+ * Describes the mailbox primary Simple Mail Transfer Protocol (SMTP)
+ * address that contains the identifiers to translate.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderIdType.php
new file mode 100644
index 00000000..96a5c01c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderIdType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AlternatePublicFolderIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes a public folder identifier to convert to another identifier format.
+ *
+ * @package php-ews\Type
+ */
+class AlternatePublicFolderIdType extends AlternateIdBaseType
+{
+ /**
+ * Contains the public folder identifier to convert.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $FolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderItemIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderItemIdType.php
new file mode 100644
index 00000000..68236698
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AlternatePublicFolderItemIdType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AlternatePublicFolderItemIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes a public folder item identifier to convert to another identifier
+ * format.
+ *
+ * @package php-ews\Type
+ */
+class AlternatePublicFolderItemIdType extends AlternatePublicFolderIdType
+{
+ /**
+ * Identifier the public folder item to convert.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $ItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AndType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AndType.php
new file mode 100644
index 00000000..5e47b401
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AndType.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AndType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that allows you to perform a Boolean AND
+ * operation between two or more search expressions.
+ *
+ * The result of the AND operation is true if all the search expressions
+ * contained within the And element are true.
+ *
+ * @package php-ews\Type
+ */
+class AndType extends MultipleOperandBooleanExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppMetadata.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppMetadata.php
new file mode 100644
index 00000000..67402b14
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppMetadata.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AppMetadata.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines metadata about a mail app.
+ *
+ * @package php-ews\Type
+ */
+class AppMetadata extends Type
+{
+ /**
+ * Identifies the URL that the user should navigate to, in order to fix an
+ * issue indicated by the AppStatus element.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ public $ActionUrl;
+
+ /**
+ * Indicates the status of the mail app.
+ *
+ * Possible values:
+ * - Null or 0: The mail app has a healthy status.
+ * - 1.0: The mail app could not be automatically updated. The mail ap
+ * needs to be re-installed from the Office Store.
+ * - 1.1: The mail app could not be automatically updated. The mail app
+ * requires increased permissions, and this requires your review and
+ * confirmation to install.
+ * - 1.2: The mail app couldn't be updated automatically. The current
+ * license has expired or is invalid. Please update the mail app from the
+ * Office Store.
+ * - 2.0: The mail app license could not be automatically updated. The
+ * license for the mail app needs to be recovered from the Office Store.
+ * - 2.1: The mail app license could not be automatically updated. The
+ * current license has expired. A new license for this app needs to be
+ * installed from the Office Store.
+ * - 3.0: The Office Store status for the mail app has changed. This may
+ * indicate that there is a problem with the mail app. Go to the mail app
+ * page in the Office Store for more information.
+ * - 3.1: The mail app has been removed from the Office Store.
+ * - 3.2: A problem has been discovered with the mail app and it has
+ * temporarily been withdrawn from the Office Store.
+ * - 3.3: The mail app will be removed from the Office Store within 30 days.
+ * - 4.0: The mail app has been automatically disabled by your mail client.
+ * - 4.1: The mail app has been disabled by Outlook for performance reasons.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ public $AppStatus;
+
+ /**
+ * The consent state of the extension.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ public $ConsentState;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ *
+ * @todo Update once documentation exists.
+ */
+ public $EnabledStatus;
+
+ /**
+ * Specifies the URL for the mail app in the Office Store.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ */
+ public $EndNodeUrl;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ExtensionType;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $InstalledBy;
+
+ /**
+ * Whether or not the extension is mandatory.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ */
+ public $IsMandatory;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $LicenseStatus;
+
+ /**
+ * The asset id of the addin in the marketplace
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ public $MarketplaceAssetId;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ProductId;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ * @todo Make a DateTime object.
+ */
+ public $TrialExpirationDate;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppType.php
new file mode 100644
index 00000000..d07f774b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AppType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines information about an XML manifest file for a mail app that is
+ * installed in a mailbox.
+ *
+ * @package php-ews\Type
+ */
+class AppType extends Type
+{
+ /**
+ * Contains the base64-encoded app manifest file.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $Manifest;
+
+ /**
+ * Contains metadata about the mail app.
+ *
+ * @since Exchange 2013 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\AppMetadata
+ */
+ public $Metadata;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToFolderFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToFolderFieldType.php
new file mode 100644
index 00000000..79b954b2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToFolderFieldType.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AppendToFolderFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * This type element is not implemented. Any request that uses this type will
+ * always return an error response.
+ *
+ * @package php-ews\Type
+ */
+class AppendToFolderFieldType extends FolderChangeDescriptionType
+{
+ /**
+ * Represents a folder that primarily contains calendar items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarFolderType
+ */
+ public $CalendarFolder;
+
+ /**
+ * Represents a Contacts folder in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactsFolderType
+ */
+ public $ContactsFolder;
+
+ /**
+ * Identifies a folder to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderType
+ */
+ public $Folder;
+
+ /**
+ * Represents a search folder that is contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchFolderType
+ */
+ public $SearchFolder;
+
+ /**
+ * Represents a Tasks folder that is contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TasksFolderType
+ */
+ public $TasksFolder;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToItemFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToItemFieldType.php
new file mode 100644
index 00000000..66315a08
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AppendToItemFieldType.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AppendToItemFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies data to append to a single property of an item during an
+ * UpdateItem operation.
+ *
+ * @package php-ews\Type
+ */
+class AppendToItemFieldType extends ItemChangeDescriptionType
+{
+ /**
+ * Represents an Exchange calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarItemType
+ */
+ public $CalendarItem;
+
+ /**
+ * Represents an Exchange contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactItemType
+ */
+ public $Contact;
+
+ /**
+ * Represents a distribution list.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistributionListType
+ */
+ public $DistributionList;
+
+ /**
+ * Represents an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemType
+ */
+ public $Item;
+
+ /**
+ * Represents a meeting cancellation in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingCancellationMessageType
+ */
+ public $MeetingCancellation;
+
+ /**
+ * Represents a meeting in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingMessageType
+ */
+ public $MeetingMessage;
+
+ /**
+ * Represents a meeting request in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingRequestMessageType
+ */
+ public $MeetingRequest;
+
+ /**
+ * Represents a meeting response in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingResponseMessageType
+ */
+ public $MeetingResponse;
+
+ /**
+ * Represents an Exchange e-mail message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MessageType
+ */
+ public $Message;
+
+ /**
+ * Represents a task in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TaskType
+ */
+ public $Task;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentIdType.php
new file mode 100644
index 00000000..7b74239b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentIdType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AttachmentIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies an item or file attachment.
+ *
+ * @package php-ews\Type
+ */
+class AttachmentIdType extends RequestAttachmentIdType
+{
+ /**
+ * Identifies the unique identifier of the root store item to which the
+ * attachment is attached.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $RootItemChangeKey;
+
+ /**
+ * Identifies the change key of the root store item to which the attachment
+ * is attached.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $RootItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentResponseShapeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentResponseShapeType.php
new file mode 100644
index 00000000..bf338ddb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentResponseShapeType.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AttachmentResponseShapeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents additional properties to return in a response to a GetAttachment
+ * request.
+ *
+ * @package php-ews\Type
+ */
+class AttachmentResponseShapeType extends Type
+{
+ /**
+ * Identifies additional properties to return in a response.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType
+ */
+ public $AdditionalProperties;
+
+ /**
+ * Identifies how the body text is formatted in the response.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\BodyTypeResponseType
+ */
+ public $BodyType;
+
+ /**
+ * Specifies whether potentially unsafe HTML content is filtered from an
+ * attachment.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $FilterHtmlContent;
+
+ /**
+ * Specifies whether the Multipurpose Internet Mail Extensions (MIME)
+ * content of an item or attachment is returned in the response.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludeMimeContent;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentType.php
new file mode 100644
index 00000000..714ffc1d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttachmentType.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AttachmentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an Exchange attachment.
+ *
+ * @package php-ews\Type
+ */
+class AttachmentType extends Type
+{
+ /**
+ * Identifies the file attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AttachmentIdType
+ */
+ public $AttachmentId;
+
+ /**
+ * Represents an identifier for the contents of an attachment. ContentId can
+ * be set to any string value. Applications can use ContentId to implement
+ * their own identification mechanisms.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ContentId;
+
+ /**
+ * Contains the Uniform Resource Identifier (URI) that corresponds to the
+ * location of the content of the attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ContentLocation;
+
+ /**
+ * Describes the Multipurpose Internet Mail Extensions (MIME) type of the
+ * attachment content.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ContentType;
+
+ /**
+ * Represents whether the attachment appears inline within an item.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsInline;
+
+ /**
+ * Represents when the file attachment was last modified.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $LastModifiedTime;
+
+ /**
+ * Represents the name of the attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Represents the size in bytes of the file attachment.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Size;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeConflictData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeConflictData.php
new file mode 100644
index 00000000..8e260105
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeConflictData.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AttendeeConflictData.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an attendee that has conflicting data.
+ *
+ * @package php-ews\Type
+ */
+abstract class AttendeeConflictData extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeType.php
new file mode 100644
index 00000000..9974c14b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/AttendeeType.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AttendeeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents attendees and resources for a meeting.
+ *
+ * @package php-ews\Type
+ */
+class AttendeeType extends Type
+{
+ /**
+ * Represents the date and time of the latest response that is received.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $LastResponseTime;
+
+ /**
+ * Identifies a fully resolved e-mail address.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+
+ /**
+ * Represents the type of recipient response that is received for a meeting.
+ *
+ * This property is only relevant to a meeting organizer's calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ResponseTypeType
+ */
+ public $ResponseType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseEmailAddressType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseEmailAddressType.php
new file mode 100644
index 00000000..6b7480d6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseEmailAddressType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseEmailAddressType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for email address types.
+ *
+ * @package php-ews\Type
+ */
+abstract class BaseEmailAddressType extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderIdType.php
new file mode 100644
index 00000000..5e524ced
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderIdType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseFolderIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base type for item identifiers.
+ *
+ * @package php-ews\Type
+ */
+abstract class BaseFolderIdType extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderType.php
new file mode 100644
index 00000000..13f79e68
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseFolderType.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for folder types.
+ *
+ * @package php-ews\Type
+ */
+abstract class BaseFolderType extends Type
+{
+ /**
+ * Represents the number of child folders that are contained within a
+ * folder.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $ChildFolderCount;
+
+ /**
+ * Contains the display name of a folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Contains the client's rights based on the permission settings for the
+ * item or folder.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EffectiveRightsType
+ */
+ public $EffectiveRights;
+
+ /**
+ * Identifies extended properties on folders.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExtendedPropertyType
+ */
+ public $ExtendedProperty;
+
+ /**
+ * Represents the folder class for a given folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $FolderClass;
+
+ /**
+ * Contains the identifier and change key of a folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $FolderId;
+
+ /**
+ * Contains information about a managed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ManagedFolderInformationType
+ */
+ public $ManagedFolderInformation;
+
+ /**
+ * Represents the identifier of the parent folder that contains the folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $ParentFolderId;
+
+ /**
+ * Represents the total count of items within a given folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $TotalCount;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseGroupByType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseGroupByType.php
new file mode 100644
index 00000000..55b96c85
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseGroupByType.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseGroupByType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for item ordering.
+ *
+ * @package php-ews\Type
+ */
+abstract class BaseGroupByType extends Type
+{
+ /**
+ * Determines the order of the groups in the grouped item array that is
+ * returned in the response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SortDirectionType
+ */
+ public $Order;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseItemIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseItemIdType.php
new file mode 100644
index 00000000..bb70fb29
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseItemIdType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseItemIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base type for item identifiers.
+ *
+ * @package php-ews\Type
+ */
+abstract class BaseItemIdType extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseNotificationEventType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseNotificationEventType.php
new file mode 100644
index 00000000..586d9c24
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseNotificationEventType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseNotificationEventType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a notification that no new activity has occurred in the mailbox.
+ *
+ * @package php-ews\Type
+ */
+class BaseNotificationEventType extends Type
+{
+ /**
+ * Represents the last valid watermark for a subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Determine if we need a WatermarkType.
+ */
+ public $Watermark;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseObjectChangedEventType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseObjectChangedEventType.php
new file mode 100644
index 00000000..804f0139
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseObjectChangedEventType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseObjectChangedEventType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an event in which an item or folder is created.
+ *
+ * @package php-ews\Type
+ */
+class BaseObjectChangedEventType extends BaseNotificationEventType
+{
+ /**
+ * Represents the identifier of the folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $FolderId;
+
+ /**
+ * Represents the identifier of the item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Represents the identifier of the folder that contains the copy.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $ParentFolderId;
+
+ /**
+ * Represents the timestamp of a copy item/folder mailbox event.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $TimeStamp;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePagingType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePagingType.php
new file mode 100644
index 00000000..345ef47e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePagingType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BasePagingType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for defining how results should be paged.
+ *
+ * @package php-ews\Type
+ */
+abstract class BasePagingType extends Type
+{
+ /**
+ * Describes the maximum number of items or conversations to return in the
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MaxEntriesReturned;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePathToElementType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePathToElementType.php
new file mode 100644
index 00000000..3344f40e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePathToElementType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\AcceptItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for a path to an element.
+ *
+ * @package php-ews\Type
+ */
+abstract class BasePathToElementType extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePermissionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePermissionType.php
new file mode 100644
index 00000000..520928c3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BasePermissionType.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BasePermissionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for permission types.
+ *
+ * @package php-ews\Type
+ */
+abstract class BasePermissionType extends Type
+{
+ /**
+ * Indicates whether a user has permission to create items in a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $CanCreateItems;
+
+ /**
+ * Indicates whether a user has permission to create subfolders in a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $CanCreateSubFolders;
+
+ /**
+ * Indicates whether a user has permission to delete items in a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PermissionActionType
+ */
+ public $DeleteItems;
+
+ /**
+ * Indicates whether a user has permission to edit items in a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PermissionActionType
+ */
+ public $EditItems;
+
+ /**
+ * Indicates whether a user is a contact for a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $IsFolderContact;
+
+ /**
+ * Indicates whether a user is the owner of a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $IsFolderOwner;
+
+ /**
+ * Indicates whether a user can view a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $IsFolderVisible;
+
+ /**
+ * Identifies a delegate user or a user who has folders access permissions.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserIdType
+ */
+ public $UserId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseSubscriptionRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseSubscriptionRequestType.php
new file mode 100644
index 00000000..be987dd9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BaseSubscriptionRequestType.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BaseSubscriptionRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for subscription requests.
+ *
+ * @package php-ews\Type
+ */
+abstract class BaseSubscriptionRequestType extends Type
+{
+ /**
+ * Contains a collection of event notifications that are used to create a
+ * subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfNotificationEventTypesType
+ */
+ public $EventTypes;
+
+ /**
+ * Contains an array of folder identifiers that are used to identify folders
+ * to monitor for event notifications.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FolderIds;
+
+ /**
+ * Indicates whether to subscribe to all available folders.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $SubscribeToAllFolders;
+
+ /**
+ * Represents an event bookmark in the mailbox events table.
+ *
+ * This is used to create a subscription starting at an event represented by
+ * the watermark.
+ *
+ * If the watermark from a Subscribe request is not found, an error response
+ * will be returned to the client. This may occur if the watermark is older
+ * than 30 days or if the watermark was never present in the mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Determine if we need a WatermarkType.
+ */
+ public $Watermark;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentAttributedValueType.php
new file mode 100644
index 00000000..edf39575
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentAttributedValueType.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BodyContentAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the body content of an item.
+ *
+ * @package php-ews\Type
+ */
+class BodyContentAttributedValueType extends Type
+{
+ /**
+ * Specifies an array of attribution information for one or more of the
+ * contacts or active directory recipients aggregated into the associated
+ * persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPersonaAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Specifies the value of a BodyContentAttributedValue element.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\BodyTypeResponseType
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentType.php
new file mode 100644
index 00000000..b637f884
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyContentType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BodyContentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the value of a BodyContentAttributedValue element.
+ *
+ * @package php-ews\Type
+ */
+class BodyContentType extends Type
+{
+ /**
+ * Identifies how the body text is formatted.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\BodyTypeResponseType
+ */
+ public $BodyType;
+
+ /**
+ * Contains the value of the body content.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyType.php
new file mode 100644
index 00000000..4af49a1f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/BodyType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\BodyType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies the body of an item.
+ *
+ * @package php-ews\Type
+ */
+class BodyType extends StringType
+{
+ /**
+ * Specifies the type of the body.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\BodyTypeType
+ */
+ public $BodyType;
+
+ /**
+ * Boolean value that indicates whether the body is truncated.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsTruncated;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEvent.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEvent.php
new file mode 100644
index 00000000..c9281c11
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEvent.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CalendarEvent.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a unique calendar item occurrence.
+ *
+ * @package php-ews\Type
+ */
+class CalendarEvent extends Type
+{
+ /**
+ * Represents the start of a calendar event.
+ *
+ * This property is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $StartTime;
+
+ /**
+ * Represents the end of a calendar event.
+ *
+ * This property is required,
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $EndTime;
+
+ /**
+ * Represents the free/busy status set for a calendar event.
+ *
+ * This property is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\LegacyFreeBusyType
+ */
+ public $BusyType;
+
+ /**
+ * Provides additional information for a calendar event.
+ *
+ * This property is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarEventDetails
+ */
+ public $CalendarEventDetails;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEventDetails.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEventDetails.php
new file mode 100644
index 00000000..94a864d2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarEventDetails.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CalendarEventDetails.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents additional information about a calendar event.
+ *
+ * @package php-ews\Type
+ */
+class CalendarEventDetails extends Type
+{
+ /**
+ * Represents the entry ID of the calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ID;
+
+ /**
+ * Indicates whether an instance of a recurring calendar item is changed
+ * from the master.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsException;
+
+ /**
+ * Indicates whether the calendar event is a meeting or an appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsMeeting;
+
+ /**
+ * Indicates whether the calendar item is private.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsPrivate;
+
+ /**
+ * Indicates whether the calendar event is an instance of a recurring
+ * calendar item or a single calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsRecurring;
+
+ /**
+ * Indicates whether a reminder has been set for the calendar event.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsReminderSet;
+
+ /**
+ * Represents the location field of the calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Location;
+
+ /**
+ * Represents the subject of the calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Subject;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarFolderType.php
new file mode 100644
index 00000000..75788398
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarFolderType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CalendarFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a folder that primarily contains calendar items.
+ *
+ * @package php-ews\Type
+ */
+class CalendarFolderType extends BaseFolderType
+{
+ /**
+ * Contains all the configured permissions for a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarPermissionSetType
+ */
+ public $PermissionSet;
+
+ /**
+ * Indicates the permissions that the user has for the calendar data that is
+ * being shared.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarPermissionReadAccessType
+ */
+ public $SharingEffectiveRights;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarItemType.php
new file mode 100644
index 00000000..0eef5324
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarItemType.php
@@ -0,0 +1,447 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CalendarItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an Exchange calendar item.
+ *
+ * @package php-ews\Type
+ */
+class CalendarItemType extends ItemType
+{
+ /**
+ * Represents the total number of calendar items that are adjacent to a
+ * meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AdjacentMeetingCount;
+
+ /**
+ * Describes all calendar items that are adjacent to a meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType
+ */
+ public $AdjacentMeetings;
+
+ /**
+ * Indicates whether a new meeting time can be proposed for a meeting by an
+ * attendee.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $AllowNewTimeProposal;
+
+ /**
+ * Represents the date and time when an attendee replied to a meeting
+ * request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $AppointmentReplyTime;
+
+ /**
+ * Specifies the sequence number of a version of an appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AppointmentSequenceNumber;
+
+ /**
+ * Specifies the status of the appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\AppointmentState
+ */
+ public $AppointmentState;
+
+ /**
+ * Represents the occurrence type of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarItemTypeType
+ */
+ public $CalendarItemType;
+
+ /**
+ * Describes the type of conferencing that is performed with a calendar
+ * item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConferenceType
+ */
+ public $ConferenceType;
+
+ /**
+ * Represents the number of meetings that conflict with the calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $ConflictingMeetingCount;
+
+ /**
+ * Identifies all items that conflict with a meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType
+ */
+ public $ConflictingMeetings;
+
+ /**
+ * Indicates the date and time that an instance of a iCalendar object was
+ * created.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $DateTimeStamp;
+
+ /**
+ * Contains an array of deleted occurrences of a recurring calendar item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfDeletedOccurrencesType
+ */
+ public $DeletedOccurrences;
+
+ /**
+ * Represents the duration of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Duration;
+
+ /**
+ * Represents the end of a duration.
+ *
+ * This element only applies to a single occurrence of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $End;
+
+ /**
+ * Represents the end time zone of the calendar item.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType
+ */
+ public $EndTimeZone;
+
+ /**
+ * Represents the first occurrence of a recurring calendar item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType
+ */
+ public $FirstOccurrence;
+
+ /**
+ * Indicates whether a calendar item or meeting request represents an
+ * all-day event.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsAllDayEvent;
+
+ /**
+ * Indicates whether an appointment or meeting has been canceled.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsCancelled;
+
+ /**
+ * Indicates whether the calendar item is a meeting or appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsMeeting;
+
+ /**
+ * Indicates whether the meeting is online.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsOnlineMeeting;
+
+ /**
+ * Indicates whether a calendar item is part of a recurring item.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsRecurring;
+
+ /**
+ * Indicates whether a response to an item is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsResponseRequested;
+
+ /**
+ * Represents the last occurrence of a recurring calendar item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\OccurrenceInfoType
+ */
+ public $LastOccurrence;
+
+ /**
+ * Represents the free/busy status of the calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\LegacyFreeBusyType
+ */
+ public $LegacyFreeBusyStatus;
+
+ /**
+ * Represents the location of a meeting or appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Location;
+
+ /**
+ * Indicates whether a meeting request has been sent to requested attendees.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $MeetingRequestWasSent;
+
+ /**
+ * Represents the time zone of the location where the meeting is hosted.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneType
+ */
+ public $MeetingTimeZone;
+
+ /**
+ * Contains the URL for the meeting workspace that is linked to by the
+ * calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $MeetingWorkspaceUrl;
+
+ /**
+ * Contains an array of recurring calendar item occurrences that have been
+ * modified so that they differ from the recurrence master item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfOccurrenceInfoType
+ */
+ public $ModifiedOccurrences;
+
+ /**
+ * Contains the status of or response to a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ResponseTypeType
+ */
+ public $MyResponseType;
+
+ /**
+ * Specifies the URL for a Microsoft NetShow online meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $NetShowUrl;
+
+ /**
+ * Represents attendees that are not required to attend a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttendeesType
+ */
+ public $OptionalAttendees;
+
+ /**
+ * Represents the organizer of a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $Organizer;
+
+ /**
+ * Represents the original start time of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $OriginalStart;
+
+ /**
+ * Contains the recurrence pattern for calendar items and meeting requests.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurrenceType
+ */
+ public $Recurrence;
+
+ /**
+ * Used to identify a specific instance of a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $RecurrenceId;
+
+ /**
+ * Represents attendees that are required to attend a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttendeesType
+ */
+ public $RequiredAttendees;
+
+ /**
+ * Represents a scheduled resource for a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttendeesType
+ */
+ public $Resources;
+
+ /**
+ * Represents the start of a calendar item.
+ *
+ * This element only applies to a single occurrence of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Start;
+
+ /**
+ * Represents the start time zone of the calendar item.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType
+ */
+ public $StartTimeZone;
+
+ /**
+ * Provides a text description of a time zone.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $TimeZone;
+
+ /**
+ * Identifies a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $UID;
+
+ /**
+ * Provides information about when a calendar item occurs.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $When;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionSetType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionSetType.php
new file mode 100644
index 00000000..135dfcc1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionSetType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CalendarPermissionSetType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Contains all the permissions that are configured for a calendar folder.
+ *
+ * @package php-ews\Type
+ */
+class CalendarPermissionSetType extends Type
+{
+ /**
+ * Contains an array of calendar permissions for a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfCalendarPermissionsType
+ */
+ public $CalendarPermissions;
+
+ /**
+ * Contains an array of unknown entries that cannot be resolved against the
+ * Active Directory directory service.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfUnknownEntriesType
+ */
+ public $UnknownEntries;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionType.php
new file mode 100644
index 00000000..6b799f0b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarPermissionType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CalendarPermissionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the access that a user has to a Calendar folder.
+ *
+ * @package php-ews\Type
+ */
+class CalendarPermissionType extends BasePermissionType
+{
+ /**
+ * Represents the permission level that a user has on a Calendar folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarPermissionLevelType
+ */
+ public $CalendarPermissionLevel;
+
+ /**
+ * Indicates whether a user has permission to read items within a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarPermissionReadAccessType
+ */
+ public $ReadItems;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarViewType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarViewType.php
new file mode 100644
index 00000000..322b6708
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CalendarViewType.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CalendarViewType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a FindItem operation as returning calendar items in a set as they
+ * appear in a calendar.
+ *
+ * @package php-ews\Type
+ */
+class CalendarViewType extends BasePagingType
+{
+ /**
+ * Identifies the end of a time span queried for calendar items.
+ *
+ * All calendar items that have a start time that is on or after EndDate
+ * will not be returned. The value of EndDate can be specified in UTC
+ * format, as in 2006-02-02T12:00:00Z, or in a format where local time and
+ * time zone offset is specified, as in 2006-02-02T04:00:00-08:00.
+ *
+ * EndDate must be greater than or equal to StartDate; otherwise an error is
+ * returned.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $EndDate;
+
+ /**
+ * Identifies the start of a time span queried for calendar items.
+ *
+ * All calendar items that have an end time that is before StartDate will
+ * not be returned. The value of StartDate can be specified in coordinated
+ * universal time (UTC) format, as in 2006-01-02T12:00:00Z, or in a format
+ * where local time and time zone offset is specified, as in
+ * 2006-01-02T04:00:00-08:00.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $StartDate;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CancelCalendarItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CancelCalendarItemType.php
new file mode 100644
index 00000000..8dd62193
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CancelCalendarItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CancelCalendarItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the response object that is used to cancel a meeting.
+ *
+ * @package php-ews\Type
+ */
+class CancelCalendarItemType extends SmartResponseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ChangeDescriptionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ChangeDescriptionType.php
new file mode 100644
index 00000000..e393f1a3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ChangeDescriptionType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ChangeDescriptionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for changes to individual properties.
+ *
+ * @package php-ews\Type
+ */
+abstract class ChangeDescriptionType extends Type
+{
+ /**
+ * Identifies extended MAPI properties to set.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType
+ */
+ public $ExtendedFieldURI;
+
+ /**
+ * Identifies frequently referenced properties by URI.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToUnindexedFieldType
+ */
+ public $FieldURI;
+
+ /**
+ * Identifies individual members of a dictionary.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToIndexedFieldType
+ */
+ public $IndexedFieldURI;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenRequestType.php
new file mode 100644
index 00000000..f77999f0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenRequestType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ClientAccessTokenRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a single token request.
+ *
+ * @package php-ews\Type
+ */
+class ClientAccessTokenRequestType extends Type
+{
+ /**
+ * Specifies the identifier of an app.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Id;
+
+ /**
+ * Specifies a token scope.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Scope;
+
+ /**
+ * Identifies the type of client access token.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ClientAccessTokenTypeType
+ */
+ public $TokenType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenType.php
new file mode 100644
index 00000000..0de0cf58
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ClientAccessTokenType.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ClientAccessTokenType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a client access token.
+ *
+ * @package php-ews\Type
+ */
+class ClientAccessTokenType extends Type
+{
+ /**
+ * Specifies the identifier of the token.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Id;
+
+ /**
+ * Specifies the type of token.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ClientAccessTokenTypeType
+ */
+ public $TokenType;
+
+ /**
+ * Specifies the encoded client access token.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $TokenValue;
+
+ /**
+ * Specifies the time, in minutes, that the token is valid.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $TTL;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CompleteNameType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CompleteNameType.php
new file mode 100644
index 00000000..900cf169
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CompleteNameType.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CompleteNameType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the complete name of a contact.
+ *
+ * @package php-ews\Type
+ */
+class CompleteNameType extends Type
+{
+ /**
+ * Represents the first name of contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $FirstName;
+
+ /**
+ * Represents the full name of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $FullName;
+
+ /**
+ * Represents the initials of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Initials;
+
+ /**
+ * Represents the last name of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $LastName;
+
+ /**
+ * Represents the middle name of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $MiddleName;
+
+ /**
+ * Represents the nickname of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Nickname;
+
+ /**
+ * Represents a suffix to a contact's name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Suffix;
+
+ /**
+ * Represents the title of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Title;
+
+ /**
+ * Represents the name used in Japan for the searchable or phonetic spelling
+ * of a Japanese first name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $YomiFirstName;
+
+ /**
+ * Represents the name used in Japan for the searchable or phonetic spelling
+ * of a Japanese last name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $YomiLastName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConflictResultsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConflictResultsType.php
new file mode 100644
index 00000000..9f07e942
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConflictResultsType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConflictResultsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Indicates the number of conflicts in an UpdateItem Operation response.
+ *
+ * @package php-ews\Type
+ */
+class ConflictResultsType extends Type
+{
+ /**
+ * Contains the number of conflicts in an UpdateItem Operation response.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Count;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConnectingSIDType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConnectingSIDType.php
new file mode 100644
index 00000000..93a61ff9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConnectingSIDType.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConnectingSIDType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an account to impersonate when you are using the
+ * ExchangeImpersonation SOAP header.
+ *
+ * @package php-ews\Type
+ */
+class ConnectingSIDType extends Type
+{
+ /**
+ * Represents the primary Simple Mail Transfer Protocol (SMTP) address of
+ * the account to use for Exchange impersonation.
+ *
+ * If the primary SMTP address is supplied, it will cost an extra Active
+ * Directory directory service lookup in order to obtain the SID of the
+ * user. We recommend that you use the SID or UPN if they are available.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PrimarySmtpAddress;
+
+ /**
+ * Represents the user principal name (UPN) of the account to use for
+ * impersonation.
+ *
+ * This should be the UPN for the domain where the user account exists.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PrincipalName;
+
+ /**
+ * Represents the security descriptor definition language (SDDL) form of the
+ * security identifier (SID) for the account to use for impersonation.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SID;
+
+ /**
+ * Represents the Simple Mail Transfer Protocol (SMTP) address of the
+ * account to use for Exchange Impersonation.
+ *
+ * If the SMTP address is supplied, it will cost an extra Active Directory
+ * lookup in order to obtain the SID of the user. We recommend that you use
+ * the SID or UPN if they are available.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $SmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConstantValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConstantValueType.php
new file mode 100644
index 00000000..8c41ac47
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConstantValueType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConstantValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a constant value in a restriction.
+ *
+ * @package php-ews\Type
+ */
+class ConstantValueType extends Type
+{
+ /**
+ * Specifies the value to compare in the restriction.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactItemType.php
new file mode 100644
index 00000000..21984ebb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactItemType.php
@@ -0,0 +1,413 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ContactItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a contact item in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class ContactItemType extends ItemType
+{
+ /**
+ * Contains the email alias of a contact.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $Alias;
+
+ /**
+ * Represents an assistant to a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $AssistantName;
+
+ /**
+ * Represents the birth date of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Birthday;
+
+ /**
+ * Represents the Home page (Web address) for the contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $BusinessHomePage;
+
+ /**
+ * Contains the names of a contact's children.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Children;
+
+ /**
+ * Represents the collection of companies that are associated with a
+ * contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Companies;
+
+ /**
+ * Represents the company name that is associated with a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $CompanyName;
+
+ /**
+ * Represents the complete name of a contact.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CompleteNameType
+ */
+ public $CompleteName;
+
+ /**
+ * Describes whether the contact is located in the Exchange store or the
+ * Active Directory directory service.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ContactSourceType
+ */
+ public $ContactSource;
+
+ /**
+ * Represents the contact's department at work.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Department;
+
+ /**
+ * Contains the directory ID of a contact.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $DirectoryId;
+
+ /**
+ * Contains SMTP information that identifies the direct reports of a
+ * contact.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $DirectReports;
+
+ /**
+ * Defines the display name of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Represents a collection of e-mail addresses for a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressDictionaryType
+ */
+ public $EmailAddresses;
+
+ /**
+ * Represents how a contact is filed in the Contacts folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $FileAs;
+
+ /**
+ * Defines how to construct what is displayed for a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\FileAsMappingType
+ */
+ public $FileAsMapping;
+
+ /**
+ * Represents a generational abbreviation that follows the full name of a
+ * contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Generation;
+
+ /**
+ * Contains a contact's given name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $GivenName;
+
+ /**
+ * Indicates whether the contact item has a file attachment that represents
+ * the contact's picture.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $HasPicture;
+
+ /**
+ * Represents a collection of instant messaging addresses for a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ImAddressDictionaryType
+ */
+ public $ImAddresses;
+
+ /**
+ * Represents the initials of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Initials;
+
+ /**
+ * Represents the job title of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $JobTitle;
+
+ /**
+ * Represents a contact's manager.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Manager;
+
+ /**
+ * Contains SMTP information that identifies the manager mailbox of the
+ * contact.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $ManagerMailbox;
+
+ /**
+ * Represents the middle name of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $MiddleName;
+
+ /**
+ * Represents mileage for a contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Mileage;
+
+ /**
+ * Contains a value that encodes the Microsoft Exchange certificate of a
+ * contact.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfBinaryType
+ */
+ public $MSExchangeCertificate;
+
+ /**
+ * Represents the nickname of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Nickname;
+
+ /**
+ * Contains supplementary contact information.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $Notes;
+
+ /**
+ * Represents the office location of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $OfficeLocation;
+
+ /**
+ * Represents a collection of telephone numbers for a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhoneNumberDictionaryType
+ */
+ public $PhoneNumbers;
+
+ /**
+ * Contains the full name of a contact, including the first and last name,
+ * spelled phonetically.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $PhoneticFullName;
+
+ /**
+ * Contains the first name of a contact, spelled phonetically.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $PhoneticFirstName;
+
+ /**
+ * Contains the last name of a contact, spelled phonetically.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $PhoneticLastName;
+
+ /**
+ * Contains a value that encodes the photo of a contact.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ */
+ public $Photo;
+
+ /**
+ * Contains a collection of physical addresses that are associated with a
+ * contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhysicalAddressDictionaryType
+ */
+ public $PhysicalAddresses;
+
+ /**
+ * Represents the display types for physical addresses.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PhysicalAddressIndexType
+ */
+ public $PostalAddressIndex;
+
+ /**
+ * Represents the profession of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Profession;
+
+ /**
+ * Represents the name of a contact's spouse/partner.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SpouseName;
+
+ /**
+ * Represents the surname of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Surname;
+
+ /**
+ * Contains a value that encodes the SMIME certificate of a contact.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfBinaryType
+ */
+ public $UserSMIMECertificate;
+
+ /**
+ * Contains the wedding anniversary of a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $WeddingAnniversary;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsFolderType.php
new file mode 100644
index 00000000..75a96e0a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsFolderType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ContactsFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a contacts folder that is contained in a mailbox.
+ *
+ * @package php-ews\Type
+ */
+class ContactsFolderType extends BaseFolderType
+{
+ /**
+ * Contains all the configured permissions for a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\PermissionSetType
+ */
+ public $PermissionSet;
+
+ /**
+ * Indicates the permissions that the user has for the contact data that is
+ * being shared.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PermissionReadAccessType
+ */
+ public $SharingEffectiveRights;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsViewType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsViewType.php
new file mode 100644
index 00000000..a3d7fde2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContactsViewType.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ContactsViewType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a search for contact items based on alphabetical display names.
+ *
+ * @package php-ews\Type
+ */
+class ContactsViewType extends BasePagingType
+{
+ /**
+ * Defines the last name in the contacts list to return in the response.
+ *
+ * If the FinalName attribute is omitted, the response will contain all
+ * subsequent contacts in the specified sort order. If the specified final
+ * name is not in the contacts list, the next alphabetical name as defined
+ * by the cultural context will be excluded.
+ *
+ * For example, if FinalName="Name", but Name is not in the contacts list,
+ * contacts that have display names of Name1 or NAME will not be included.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $FinalName;
+
+ /**
+ * Defines the first name in the contacts list to return in the response.
+ *
+ * If the specified initial name is not in the contacts list, the next
+ * alphabetical name as defined by the cultural context will be returned,
+ * except if the next name comes after FinalName.
+ *
+ * If the InitialName attribute is omitted, the response will contain a list
+ * of contacts that starts with the first name in the contact list.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $InitialName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContainsExpressionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContainsExpressionType.php
new file mode 100644
index 00000000..099623ea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContainsExpressionType.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ContainsExpressionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that determines whether a given property
+ * contains the supplied constant string value.
+ *
+ * @package php-ews\Type
+ */
+class ContainsExpressionType extends SearchExpressionType
+{
+ /**
+ * Identifies a constant value in a restriction.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConstantValueType
+ */
+ public $Constant;
+
+ /**
+ * Determines whether the search ignores cases and spaces.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ContainmentComparisonType
+ */
+ public $ContainmentComparison;
+
+ /**
+ * Identifies the boundaries of a search.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ContainmentModeType
+ */
+ public $ContainmentMode;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContextPropertyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContextPropertyType.php
new file mode 100644
index 00000000..666079b5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ContextPropertyType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ContextPropertyType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the context for an item.
+ *
+ * @package php-ews\Type
+ */
+class ContextPropertyType extends Type
+{
+ /**
+ * Specifies the key of the context.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ public $Key;
+
+ /**
+ * Specifies the value of the context.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationActionType.php
new file mode 100644
index 00000000..b2e0c7ea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationActionType.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConversationActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single action to be applied to a single conversation.
+ *
+ * @package php-ews\Type
+ */
+class ConversationActionType extends Type
+{
+ /**
+ * Contains the action to perform on the conversation specified by the
+ * ConversationId element.
+ *
+ * This element must be present.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConversationActionTypeType
+ */
+ public $Action;
+
+ /**
+ * Contains a collection of strings that identify the categories to which
+ * items in a conversation belong.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Categories;
+
+ /**
+ * Indicates the folder that is targeted for actions that use folders.
+ *
+ * This element must be present when copying, deleting, moving, and setting
+ * read state on conversation items in a target folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $ContextFolderId;
+
+ /**
+ * Contains the identifier of the conversation that will have the action
+ * specified by the Action element applied to items in the conversation.
+ *
+ * This element must be present.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ConversationId;
+
+ /**
+ * Contains the date and time that a conversation was last synchronized.
+ *
+ * This element must be present when trying to delete all items in a
+ * conversation that were received up to the specified time.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $ConversationLastSyncTime;
+
+ /**
+ * Indicates how items in a conversation are deleted.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DisposalType
+ */
+ public $DeleteType;
+
+ /**
+ * Indicates the destination folder for copy and move actions.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $DestinationFolderId;
+
+ /**
+ * Specifies a flag that enables deletion for all new items in a
+ * conversation.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $EnableAlwaysDelete;
+
+ /**
+ * Indicates whether a message has been read.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $IsRead;
+
+ /**
+ * Indicates whether the response is sent as soon as the action starts
+ * processing on the server or whether the response is sent after the action
+ * has completed.
+ *
+ * This element must be present for the response to be sent asynchronous to
+ * the requested action.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $ProcessRightAway;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationNodeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationNodeType.php
new file mode 100644
index 00000000..1b18f705
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationNodeType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConversationNodeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a node in a conversation.
+ *
+ * @package php-ews\Type
+ */
+class ConversationNodeType extends Type
+{
+ /**
+ * Represents the Internet message identifier of an item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $InternetMessageId;
+
+ /**
+ * Specifies all the items in the conversation node.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType
+ */
+ public $Items;
+
+ /**
+ * Specifies the identifier of the parent Internet message.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ParentInternetMessageId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationResponseType.php
new file mode 100644
index 00000000..c39634d3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationResponseType.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConversationResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a single conversation.
+ *
+ * @package php-ews\Type
+ */
+class ConversationResponseType extends Type
+{
+ /**
+ * Indicates whether the conversation can be deleted.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $CanDelete;
+
+ /**
+ * Contains the identifier of the conversation.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ConversationId;
+
+ /**
+ * Specifies a collection of conversation nodes.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfConversationNodesType
+ */
+ public $ConversationNodes;
+
+ /**
+ * Specifies the synchronization state of a conversation.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $SyncState;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationShape.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationShape.php
new file mode 100644
index 00000000..0281ad08
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationShape.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConversationShape.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies the property set to return in a FindConversation operation
+ * response.
+ *
+ * @package php-ews\Type
+ */
+class ConversationShape extends Type
+{
+ /**
+ * Identifies additional properties for use in the request.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType
+ */
+ public $AdditionalProperties;
+
+ /**
+ * Identifies the set of properties to return in the response.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType
+ */
+ public $BaseShape;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationType.php
new file mode 100644
index 00000000..f37f0263
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ConversationType.php
@@ -0,0 +1,310 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ConversationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single conversation.
+ *
+ * @package php-ews\Type
+ */
+class ConversationType extends Type
+{
+ /**
+ * Contains a collection of strings that identify the categories that are
+ * applied to all conversation items in the current folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Categories;
+
+ /**
+ * Represents the identifier of a conversation.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ConversationId;
+
+ /**
+ * Represents the conversation topic.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $ConversationTopic;
+
+ /**
+ * Contains the aggregated flag status for conversation items in the current
+ * folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\FlagStatusType
+ */
+ public $FlagStatus;
+
+ /**
+ * Contains the category list for all conversation items in a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $GlobalCategories;
+
+ /**
+ * Contains the aggregated flag status for all conversation items in a
+ * mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\FlagStatusType
+ */
+ public $GlobalFlagStatus;
+
+ /**
+ * Contains a value that indicates whether at least one conversation item in
+ * a mailbox has an attachment.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $GlobalHasAttachments;
+
+ /**
+ * Contains the aggregated importance for all conversation items in a
+ * mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ImportanceChoicesType
+ */
+ public $GlobalImportance;
+
+ /**
+ * Contains a list of item classes that represents all the item classes of
+ * the conversation items in a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfItemClassType
+ */
+ public $GlobalItemClasses;
+
+ /**
+ * Contains the collection of item identifiers for all conversation items in
+ * a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $GlobalItemIds;
+
+ /**
+ * Contains the delivery time of the message that was last received in this
+ * conversation across all folders in the mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $GlobalLastDeliveryTime;
+
+ /**
+ * Contains the total number of conversation items in the mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var integer
+ */
+ public $GlobalMessageCount;
+
+ /**
+ * Contains the size of the conversation calculated from the size of all
+ * conversation items in the mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var integer
+ */
+ public $GlobalSize;
+
+ /**
+ * Contains the recipient list of a conversation aggregated across a
+ * mailbox.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $GlobalUniqueRecipients;
+
+ /**
+ * Contains a list of all the senders of conversation items in the mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $GlobalUniqueSenders;
+
+ /**
+ * Contains a list of all the people who have sent messages that are
+ * currently unread in this conversation across all folders in the mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $GlobalUniqueUnreadSenders;
+
+ /**
+ * Contains a count of all the unread conversation items in the mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var integer
+ */
+ public $GlobalUnreadCount;
+
+ /**
+ * Contains a value that indicates whether at least one conversation item in
+ * the current folder has an attachment.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $HasAttachments;
+
+ /**
+ * Contains the aggregated importance for all conversation items in the
+ * current folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ImportanceChoicesType
+ */
+ public $Importance;
+
+ /**
+ * Contains a list of item classes that represents all the item classes of
+ * the conversation items in the current folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfItemClassType
+ */
+ public $ItemClasses;
+
+ /**
+ * Contains the collection of item identifiers for all conversation items in
+ * the current folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType
+ */
+ public $ItemIds;
+
+ /**
+ * Contains the delivery time of the message that was last received in this
+ * conversation in the current folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $LastDeliveryTime;
+
+ /**
+ * Contains the total number of conversation items in the current folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var integer
+ */
+ public $MessageCount;
+
+ /**
+ * Contains the conversation size calculated from the size of all
+ * conversation items in the current folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var integer
+ */
+ public $Size;
+
+ /**
+ * Contains the recipient list of a conversation aggregated from a
+ * particular folder.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $UniqueRecipients;
+
+ /**
+ * Contains a list of all the senders of conversation items in the current
+ * folder.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $UniqueSenders;
+
+ /**
+ * Contains a list of all the people who have sent messages that are
+ * currently unread in this conversation in the current folder.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $UniqueUnreadSenders;
+
+ /**
+ * Contains the count of unread conversation items within a folder.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var integer
+ */
+ public $UnreadCount;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CreateRuleOperationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CreateRuleOperationType.php
new file mode 100644
index 00000000..d26153f7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/CreateRuleOperationType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\CreateRuleOperationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an operation to create a new Inbox rule.
+ *
+ * @package php-ews\Type
+ */
+class CreateRuleOperationType extends RuleOperationType
+{
+ /**
+ * Represents a rule to be created in a user's mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RuleType
+ */
+ public $Rule;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRecurrencePatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRecurrencePatternType.php
new file mode 100644
index 00000000..70129f8e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRecurrencePatternType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DailyRecurrencePatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the frequency, in days, in which a calendar item or a task recurs.
+ *
+ * @package php-ews\Type
+ */
+class DailyRecurrencePatternType extends IntervalRecurrencePatternBaseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRegeneratingPatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRegeneratingPatternType.php
new file mode 100644
index 00000000..55fd1ef4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DailyRegeneratingPatternType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DailyRegeneratingPatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the frequency, in days, in which a task is regenerated.
+ *
+ * @package php-ews\Type
+ */
+class DailyRegeneratingPatternType extends RegeneratingPatternBaseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeclineItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeclineItemType.php
new file mode 100644
index 00000000..a8cd62bb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeclineItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DeclineItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a Decline reply to a meeting request.
+ *
+ * @package php-ews\Type
+ */
+class DeclineItemType extends WellKnownResponseObjectType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegatePermissionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegatePermissionsType.php
new file mode 100644
index 00000000..09f82581
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegatePermissionsType.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DelegatePermissionsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Contains the delegate permission-level settings for a user.
+ *
+ * @package php-ews\Type
+ */
+class DelegatePermissionsType extends Type
+{
+ /**
+ * Contains the permissions for the default Calendar folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DelegateFolderPermissionLevelType
+ */
+ public $CalendarFolderPermissionLevel;
+
+ /**
+ * Contains the permissions for the default Contacts folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DelegateFolderPermissionLevelType
+ */
+ public $ContactsFolderPermissionLevel;
+
+ /**
+ * Contains the permissions for the default Inbox folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DelegateFolderPermissionLevelType
+ */
+ public $InboxFolderPermissionLevel;
+
+ /**
+ * Contains the permissions for the default Journal folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DelegateFolderPermissionLevelType
+ */
+ public $JournalFolderPermissionLevel;
+
+ /**
+ * Contains the permissions for the default Notes folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DelegateFolderPermissionLevelType
+ */
+ public $NotesFolderPermissionLevel;
+
+ /**
+ * Contains the permissions for the default Task folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DelegateFolderPermissionLevelType
+ */
+ public $TasksFolderPermissionLevel;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegateUserType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegateUserType.php
new file mode 100644
index 00000000..cad91d97
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DelegateUserType.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DelegateUserType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a single delegate to add or update in a mailbox or a delegate
+ * returned in a delegate management response.
+ *
+ * @package php-ews\Type
+ */
+class DelegateUserType extends Type
+{
+ /**
+ * Contains the delegate permission level settings.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\DelegatePermissionsType
+ */
+ public $DelegatePermissions;
+
+ /**
+ * Indicates whether a delegate receives copies of meeting-related messages
+ * that are addressed to the principal.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $ReceiveCopiesOfMeetingMessages;
+
+ /**
+ * Identifies the delegate.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserIdType
+ */
+ public $UserId;
+
+ /**
+ * Indicates whether a delegate has permission to view private calendar
+ * items in the principal's mailbox.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $ViewPrivateItems;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteFolderFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteFolderFieldType.php
new file mode 100644
index 00000000..d9b68136
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteFolderFieldType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DeleteFolderFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an operation to delete a given property from a folder during an
+ * UpdateFolder call.
+ *
+ * @package php-ews\Type
+ */
+class DeleteFolderFieldType extends FolderChangeDescriptionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteItemFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteItemFieldType.php
new file mode 100644
index 00000000..852ca0ea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteItemFieldType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DeleteItemFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an operation to delete a given property from an item during an
+ * UpdateItem call.
+ *
+ * @package php-ews\Type
+ */
+class DeleteItemFieldType extends ItemChangeDescriptionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteRuleOperationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteRuleOperationType.php
new file mode 100644
index 00000000..6f98dc05
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeleteRuleOperationType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DeleteRuleOperationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an operation to delete an existing Inbox rule.
+ *
+ * @package php-ews\Type
+ */
+class DeleteRuleOperationType extends RuleOperationType
+{
+ /**
+ * Specifies the identifier of the rule to delete.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $RuleId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeletedOccurrenceInfoType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeletedOccurrenceInfoType.php
new file mode 100644
index 00000000..3dcb6462
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DeletedOccurrenceInfoType.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DeletedOccurrenceInfoType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a deleted occurrence of a recurring calendar item.
+ *
+ * @package php-ews\Type
+ */
+class DeletedOccurrenceInfoType extends Type
+{
+ /**
+ * Represents the start time of a deleted occurrence of a recurring calendar
+ * item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Start;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DirectoryEntryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DirectoryEntryType.php
new file mode 100644
index 00000000..81d777c1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DirectoryEntryType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DirectoryEntryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a directory entry.
+ *
+ * @package php-ews\Type
+ */
+class DirectoryEntryType extends Type
+{
+ /**
+ * An identifier that contains an email address and display name that
+ * represents a meeting room.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Id;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DiscoverySearchConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DiscoverySearchConfigurationType.php
new file mode 100644
index 00000000..208a6b0e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DiscoverySearchConfigurationType.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DiscoverySearchConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a configuration for eDiscovery search.
+ *
+ * @package php-ews\Type
+ */
+class DiscoverySearchConfigurationType extends Type
+{
+ /**
+ * Specifies the identity of a hold that preserves the mailbox items.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $InPlaceHoldIdentity;
+
+ /**
+ * Identifies the culture to be used for the culture-specific format of date
+ * ranges.
+ *
+ * It also specifies the language used in a search query.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Language;
+
+ /**
+ * Specifies the managing organization.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ManagedByOrganization;
+
+ /**
+ * Specifies the identifier of the search.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SearchId;
+
+ /**
+ * Specifies the name of an eDiscovery search query.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SearchQuery;
+
+ /**
+ * Contains a list of mailboxes.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSearchableMailboxesType
+ */
+ public $SearchableMailboxes;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedFolderIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedFolderIdType.php
new file mode 100644
index 00000000..f0e39068
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedFolderIdType.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DistinguishedFolderIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies folders that can be referenced by name.
+ *
+ * @package php-ews\Type
+ */
+class DistinguishedFolderIdType extends BaseFolderIdType
+{
+ /**
+ * Contains a string that identifies a version of a folder that is
+ * identified by the Id attribute.
+ *
+ * This attribute is optional. Use this attribute to make sure that the
+ * correct version of a folder is used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ChangeKey;
+
+ /**
+ * Identifies a default folder.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType
+ */
+ public $Id;
+
+ /**
+ * Identifies a primary SMTP address.
+ *
+ * Proxy addresses are not allowed.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedGroupByType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedGroupByType.php
new file mode 100644
index 00000000..37166b83
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistinguishedGroupByType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DistinguishedGroupByType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents standard groupings for FindItem queries.
+ *
+ * @package php-ews\Type
+ */
+class DistinguishedGroupByType extends BaseGroupByType
+{
+ /**
+ * Represents the standard grouping and aggregating mechanisms for a grouped
+ * FindItem operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\StandardGroupByType
+ */
+ public $StandardGroupBy;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistributionListType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistributionListType.php
new file mode 100644
index 00000000..b366d224
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/DistributionListType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\DistributionListType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a distribution list.
+ *
+ * @package php-ews\Type
+ */
+class DistributionListType extends ItemType
+{
+ /**
+ * Describes whether the contact is located in the Exchange store or in
+ * Active Directory Domain Services (AD DS).
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ContactSourceType
+ */
+ public $ContactSource;
+
+ /**
+ * Defines the display name of a distribution list.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Represents how a distribution list is filed in the Contacts folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $FileAs;
+
+ /**
+ * Contains a list of members of the distribution list.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\MembersListType
+ */
+ public $Members;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Duration.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Duration.php
new file mode 100644
index 00000000..5f5261d3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Duration.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\Duration.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a time span.
+ *
+ * @package php-ews\Type
+ */
+class Duration extends Type
+{
+ /**
+ * Represents the end of the time span.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $EndTime;
+
+ /**
+ * Represents the start of the time span.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $StartTime;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EffectiveRightsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EffectiveRightsType.php
new file mode 100644
index 00000000..16306ce0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EffectiveRightsType.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\EffectiveRightsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the client's rights based on the permission settings for an item
+ * or folder.
+ *
+ * @package php-ews\Type
+ */
+class EffectiveRightsType extends Type
+{
+ /**
+ * Indicates whether a client can create an associated contents table.
+ *
+ * This property is only used on folder objects.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $CreateAssociated;
+
+ /**
+ * Indicates whether a client can create a contents table.
+ *
+ * This property is only used on folder objects.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $CreateContents;
+
+ /**
+ * Indicates whether a client can create a hierarchy table.
+ *
+ * This property is only used on folder objects.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $CreateHierarchy;
+
+ /**
+ * Indicates whether a client can delete a folder or item.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $Delete;
+
+ /**
+ * Indicates whether a client can modify a folder or item.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $Modify;
+
+ /**
+ * Indicates whether a client can read a folder or item.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var boolean
+ */
+ public $Read;
+
+ /**
+ * Indicates whether a private item can be viewed.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $ViewPrivateItems;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressAttributedValueType.php
new file mode 100644
index 00000000..31031970
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressAttributedValueType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\EmailAddressAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an instance of an array of email addresses and their associated
+ * attributions.
+ *
+ * @package php-ews\Type
+ */
+class EmailAddressAttributedValueType extends Type
+{
+ /**
+ * Specifies an array of attributions for its associated Value element.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfValueAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Specifies the value of an EmailAddress associated with an attributions array.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryEntryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryEntryType.php
new file mode 100755
index 00000000..bdd5a54b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryEntryType.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\EmailAddressDictionaryEntryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single e-mail address for a contact.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a common EntryType class.
+ * @todo Create a common TextEntryType class.
+ */
+class EmailAddressDictionaryEntryType extends Type
+{
+ /**
+ * The email address represented by this entry.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $_;
+
+ /**
+ * Identifies the e-mail address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\EmailAddressKeyType
+ */
+ public $Key;
+
+ /**
+ * Defines the mailbox type of a mailbox user.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MailboxTypeType
+ */
+ public $MailboxType;
+
+ /**
+ * Defines the name of the mailbox user.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Defines the routing that is used for the mailbox.
+ *
+ * This attribute is optional and defaults to SMTP.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\RoutingType
+ */
+ public $RoutingType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryType.php
new file mode 100644
index 00000000..c09fc492
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressDictionaryType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\EmailAddressDictionaryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a collection of e-mail addresses for a contact.
+ *
+ * @package php-ews\Type
+ */
+class EmailAddressDictionaryType extends Type
+{
+ /**
+ * Represents a single e-mail address for a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressDictionaryEntryType
+ */
+ public $Entry;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressType.php
new file mode 100644
index 00000000..cb98fad8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EmailAddressType.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\EmailAddressType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifier for a fully resolved email address
+ *
+ * @package php-ews\Type
+ */
+class EmailAddressType extends BaseEmailAddressType
+{
+ /**
+ * The e-mail address that is represented.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $EmailAddress;
+
+ /**
+ * Specifies the item identifier for the e-mail address.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Specifies the type of mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MailboxTypeType
+ */
+ public $MailboxType;
+
+ /**
+ * Specifies the name of the mailbox that is associated with the e-mail
+ * address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Specifies the type of routing for the e-mail address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\RoutingType
+ */
+ public $RoutingType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EncryptedSharedFolderDataType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EncryptedSharedFolderDataType.php
new file mode 100644
index 00000000..9e394097
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EncryptedSharedFolderDataType.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\EncryptedSharedFolderDataType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the encrypted data that a client can use to authorize the sharing
+ * of its calendar or contact data with other clients.
+ *
+ * @package php-ews\Type
+ */
+class EncryptedSharedFolderDataType extends Type
+{
+ /**
+ * Contains encrypted data that represents the shared data.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Determine if we need an EncryptedDataContainerType implementation.
+ */
+ public $Data;
+
+ /**
+ * Contains encrypted data that represents the identification token for the
+ * shared data.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Determine if we need an EncryptedDataContainerType implementation.
+ */
+ public $Token;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EndDateRecurrenceRangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EndDateRecurrenceRangeType.php
new file mode 100644
index 00000000..68aa4116
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/EndDateRecurrenceRangeType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\EndDateRecurrenceRangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the start date and the end date of an item recurrence pattern.
+ *
+ * @package php-ews\Type
+ */
+class EndDateRecurrenceRangeType extends RecurrenceRangeBaseType
+{
+ /**
+ * Represents the end date of a recurring task or calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a date object that extends DateTime.
+ */
+ public $EndDate;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExchangeImpersonationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExchangeImpersonationType.php
new file mode 100644
index 00000000..eeec0647
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExchangeImpersonationType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ExchangeImpersonationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the account to impersonate within a request.
+ *
+ * @package php-ews\Type
+ */
+class ExchangeImpersonationType extends Type
+{
+ /**
+ * Represents an account to impersonate when you are using the
+ * ExchangeImpersonation SOAP header.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConnectingSIDType
+ */
+ public $ConnectingSID;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesType.php
new file mode 100644
index 00000000..c0de79c3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ExcludesType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a bitwise mask of a specified property and a supplied value.
+ *
+ * @package php-ews\Type
+ */
+class ExcludesType extends SearchExpressionType
+{
+ /**
+ * Represents a hexadecimal or decimal mask to be used during an Excludes
+ * restriction operation.
+ *
+ * If the bitmask represents a hexadecimal number, it must be prefixed by 0x
+ * or 0X. Otherwise, it will be considered a decimal number.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExcludesValueType
+ */
+ public $Bitmask;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesValueType.php
new file mode 100644
index 00000000..17a67804
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExcludesValueType.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ExcludesValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a hexadecimal or decimal mask to be used during an Excludes
+ * restriction operation.
+ *
+ * @package php-ews\Type
+ */
+class ExcludesValueType extends Type
+{
+ /**
+ * Represents a decimal or hexadecimal bitmask.
+ *
+ * The value is represented by the following regular expression:
+ * ((0x|0X)[0-9A-Fa-f]*)|([0-9]*).
+ *
+ * The following are examples of hexadecimal values for this attribute:
+ * - 0x12AF
+ * - 0X334AE
+ *
+ * The following are examples of decimal values for this attribute:
+ * - 10
+ * - 255
+ * - 4562
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Determine if we need an ExcludesAttributeType class.
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExistsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExistsType.php
new file mode 100644
index 00000000..0cf02869
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExistsType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ExistsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that returns true if the supplied property
+ * exists on an item.
+ *
+ * @package php-ews\Type
+ */
+class ExistsType extends SearchExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedAttributeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedAttributeType.php
new file mode 100644
index 00000000..5f3d4386
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedAttributeType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ExtendedAttributeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Internal use only.
+ *
+ * @package php-ews\Type
+ */
+class ExtendedAttributeType extends Type
+{
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyAttributedValueType.php
new file mode 100644
index 00000000..97688a26
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyAttributedValueType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ExtendedPropertyAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an extended property for a persona.
+ *
+ * @package php-ews\Type
+ */
+class ExtendedPropertyAttributedValueType extends Type
+{
+ /**
+ * Specifies an array of attributions for its associated Value element.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfValueAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Specifies an extended property for a persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExtendedPropertyType
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyType.php
new file mode 100644
index 00000000..c57bd3f4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ExtendedPropertyType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ExtendedPropertyType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies extended MAPI properties on folders and items.
+ *
+ * @package php-ews\Type
+ */
+class ExtendedPropertyType extends Type
+{
+ /**
+ * Identifies an extended MAPI property to get, set, or create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType
+ */
+ public $ExtendedFieldURI;
+
+ /**
+ * Contains the value of single-valued MAPI extended property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Value;
+
+ /**
+ * Contains a collection of values for a multivalued extended MAPI property.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPropertyValuesType
+ */
+ public $Values;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FailedSearchMailboxType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FailedSearchMailboxType.php
new file mode 100644
index 00000000..74c2cd8e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FailedSearchMailboxType.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FailedSearchMailboxType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies the error message for a mailbox that failed on search.
+ *
+ * @package php-ews\Type
+ */
+class FailedSearchMailboxType extends Type
+{
+ /**
+ * Specifies the error code of the mailbox that failed the search.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $ErrorCode;
+
+ /**
+ * Represents the reason for the validation error.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ErrorMessage;
+
+ /**
+ * Specifies whether the mailbox is an archive.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsArchive;
+
+ /**
+ * Contains an identifier for the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldOrderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldOrderType.php
new file mode 100644
index 00000000..fde9a9bc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldOrderType.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FieldOrderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single field by which to sort results and indicates the
+ * direction for the sort.
+ *
+ * @package php-ews\Type
+ */
+class FieldOrderType extends Type
+{
+ /**
+ * Identifies MAPI properties.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType
+ */
+ public $ExtendedFieldURI;
+
+ /**
+ * Identifies frequently referenced properties by URI.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToUnindexedFieldType
+ */
+ public $FieldURI;
+
+ /**
+ * Identifies individual members of a dictionary.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToIndexedFieldType
+ */
+ public $IndexedFieldURI;
+
+ /**
+ * Describes the sort order direction.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SortDirectionType
+ */
+ public $Order;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldURIOrConstantType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldURIOrConstantType.php
new file mode 100644
index 00000000..8fbd38fa
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FieldURIOrConstantType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FieldURIOrConstantType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents either a property or a constant value to be used when comparing
+ * with another property.
+ *
+ * @package php-ews\Type
+ */
+class FieldURIOrConstantType extends SearchExpressionType
+{
+ /**
+ * Identifies a constant value in a restriction.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ConstantValueType
+ */
+ public $Constant;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FileAttachmentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FileAttachmentType.php
new file mode 100644
index 00000000..6dc28090
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FileAttachmentType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FileAttachmentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a file that is attached to an item in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class FileAttachmentType extends AttachmentType
+{
+
+ /**
+ * Contains the Base64-encoded contents of the file attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Consider using an object that takes a file stream and does the
+ * base64 conversion.
+ */
+ public $Content;
+
+ /**
+ * Indicates whether the file attachment is a contact picture.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsContactPhoto;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindFolderParentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindFolderParentType.php
new file mode 100644
index 00000000..f04a3b7a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindFolderParentType.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FindFolderParentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the results of a search of a single root folder during a
+ * FindFolder operation.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a FindResponsePagingAttributes trait.
+ */
+class FindFolderParentType extends Type
+{
+ /**
+ * Represents the next denominator to use for the next request when you are
+ * using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AbsoluteDenominator;
+
+ /**
+ * Contains an array of folders found by using the FindFolder operation.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFoldersType
+ */
+ public $Folders;
+
+ /**
+ * Indicates whether the current results contain the last item in the query
+ * so that additional paging is not needed.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludesLastItemInRange;
+
+ /**
+ * Represents the next index that should be used for the next request when
+ * you are using an indexed page view.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $IndexedPagingOffset;
+
+ /**
+ * Represents the new numerator value to use for the next request when you
+ * are using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumeratorOffset;
+
+ /**
+ * Represents the total number of items in the view.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $TotalItemsInView;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindItemParentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindItemParentType.php
new file mode 100644
index 00000000..afb8a2a2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindItemParentType.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FindItemParentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the results of a search of a single root folder during a FindItem
+ * operation.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a FindResponsePagingAttributes trait.
+ */
+class FindItemParentType extends Type
+{
+ /**
+ * Represents the next denominator to use for the next request when you are
+ * using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AbsoluteDenominator;
+
+ /**
+ * Contains a collection of groups found that have the search and
+ * aggregation criteria identified in the FindItem operation request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfGroupedItemsType
+ */
+ public $Groups;
+
+ /**
+ * Indicates whether the current results contain the last item in the query
+ * so that additional paging is not needed.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludesLastItemInRange;
+
+ /**
+ * Represents the next index that should be used for the next request when
+ * you are using an indexed page view.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $IndexedPagingOffset;
+
+ /**
+ * Contains an array of items found that have the search criteria identified
+ * in the FindItem operation request.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRealItemsType
+ */
+ public $Items;
+
+ /**
+ * Represents the new numerator value to use for the next request when you
+ * are using fraction page views.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumeratorOffset;
+
+ /**
+ * Represents the total number of items in the view.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $TotalItemsInView;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindMessageTrackingSearchResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindMessageTrackingSearchResultType.php
new file mode 100644
index 00000000..057b3ad6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FindMessageTrackingSearchResultType.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FindMessageTrackingSearchResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single message result for a FindMessageTrackingReportResponse
+ * element.
+ *
+ * @package php-ews\Type
+ */
+class FindMessageTrackingSearchResultType extends Type
+{
+ /**
+ * Contains the name of the server in the forest that first accepted the
+ * message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $FirstHopServer;
+
+ /**
+ * Contains an internal ID that identifies the message in the transport
+ * database.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $MessageTrackingReportId;
+
+ /**
+ * Contains the name of the server in the forest that previously accepted
+ * the message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $PreviousHopServer;
+
+ /**
+ * Contains a list of one or more tracking properties.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType
+ */
+ public $Properties;
+
+ /**
+ * Contains contact information for the alleged sender of an e-mail message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $PurportedSender;
+
+ /**
+ * Contains a list of e-mail addresses that received this message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $Recipients;
+
+ /**
+ * Contains the e-mail message sender’s address.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Sender;
+
+ /**
+ * Contains the e-mail message subject.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $Subject;
+
+ /**
+ * Contains the time that the message was submitted.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $SubmittedTime;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeDescriptionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeDescriptionType.php
new file mode 100644
index 00000000..2e85c99a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeDescriptionType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FolderChangeDescriptionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for changes to individual folder properties.
+ *
+ * @package php-ews\Type
+ */
+class FolderChangeDescriptionType extends ChangeDescriptionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeType.php
new file mode 100644
index 00000000..0b0850c7
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderChangeType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FolderChangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a collection of changes to be performed on a single folder.
+ *
+ * @package php-ews\Type
+ */
+class FolderChangeType extends Type
+{
+ /**
+ * Identifies MicrosoftExchange Server 2007 folders that can be referenced by
+ * name.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistinguishedFolderIdType
+ */
+ public $DistinguishedFolderId;
+
+ /**
+ * Contains the identifier and change key of a folder to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $FolderId;
+
+ /**
+ * Defines the type of update that is performed on a folder that is
+ * identified by either the FolderId or DistinguishedFolderId element.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfFolderChangeDescriptionsType
+ */
+ public $Updates;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderIdType.php
new file mode 100644
index 00000000..7d1f428f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderIdType.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FolderIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the identifier of the parent folder that contains the item or
+ * folder.
+ *
+ * @package php-ews\Type
+ */
+class FolderIdType extends BaseFolderIdType
+{
+ /**
+ * Contains a string that identifies a version of a folder that is
+ * identified by the Id attribute.
+ *
+ * This attribute is optional. Use this attribute to make sure that the
+ * correct version of a folder is used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ChangeKey;
+
+ /**
+ * Contains a string that identifies a folder in the Exchange store.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Id;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderResponseShapeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderResponseShapeType.php
new file mode 100644
index 00000000..03c65812
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderResponseShapeType.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FolderResponseShapeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the folder properties to include in a GetFolder, FindFolder, or
+ * SyncFolderHierarchy response.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a common ResponseShapeType.
+ */
+class FolderResponseShapeType extends Type
+{
+ /**
+ * Identifies additional properties to return in a response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType
+ */
+ public $AdditionalProperties;
+
+ /**
+ * Identifies the basic configuration of properties to return in a response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType
+ */
+ public $BaseShape;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderType.php
new file mode 100644
index 00000000..b640e2b8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FolderType.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a folder to create, get, find, synchronize, or update.
+ *
+ * @package php-ews\Type
+ */
+class FolderType extends BaseFolderType
+{
+ /**
+ * Contains all the configured permissions for a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\PermissionSetType
+ */
+ public $PermissionSet;
+
+ /**
+ * Represents the count of unread items within a given folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $UnreadCount;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ForwardItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ForwardItemType.php
new file mode 100644
index 00000000..ddd6ab89
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ForwardItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ForwardItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an Exchange store item to forward to recipients.
+ *
+ * @package php-ews\Type
+ */
+class ForwardItemType extends SmartResponseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FractionalPageViewType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FractionalPageViewType.php
new file mode 100644
index 00000000..87b73cbf
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FractionalPageViewType.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FractionalPageViewType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes where the paged view starts and the maximum number of folders
+ * returned in a FindFolder request.
+ *
+ * @package php-ews\Type
+ */
+class FractionalPageViewType extends BasePagingType
+{
+ /**
+ * Represents the denominator of the fractional offset from the start of the
+ * total number of folders in the result set.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Denominator;
+
+ /**
+ * Represents the numerator of the fractional offset from the start of the
+ * result set.
+ *
+ * The numerator must be equal to or less than the denominator.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Numerator;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyResponseType.php
new file mode 100644
index 00000000..5acdf47b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyResponseType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FreeBusyResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the free/busy information for a single mailbox user.
+ *
+ * @package php-ews\Type
+ */
+class FreeBusyResponseType extends Type
+{
+ /**
+ * Contains availability information for a specific user.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FreeBusyView
+ */
+ public $FreeBusyView;
+
+ /**
+ * Provides descriptive information about the response status.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType
+ */
+ public $ResponseMessage;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyView.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyView.php
new file mode 100644
index 00000000..0beeb9fc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyView.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FreeBusyView.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents availability information for a specific user.
+ *
+ * @package php-ews\Type
+ */
+class FreeBusyView extends Type
+{
+ /**
+ * Contains a set of unique calendar item occurrences that represent the
+ * requested user's availability.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfCalendarEvent
+ */
+ public $CalendarEventArray;
+
+ /**
+ * Represents the type of requested free/busy information returned in the
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\FreeBusyViewType
+ */
+ public $FreeBusyViewType;
+
+ /**
+ * Contains the merged free/busy stream of data.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $MergedFreeBusy;
+
+ /**
+ * Represents the time zone settings and working hours for the requested
+ * mailbox user.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\WorkingHours
+ */
+ public $WorkingHours;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyViewOptionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyViewOptionsType.php
new file mode 100644
index 00000000..fda79cf3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/FreeBusyViewOptionsType.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\FreeBusyViewOptionsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the type of free/busy information returned in a response.
+ *
+ * @package php-ews\Type
+ */
+class FreeBusyViewOptionsType extends Type
+{
+ /**
+ * Represents the time difference between two successive slots in the
+ * FreeBusyMerged view.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MergedFreeBusyIntervalInMinutes;
+
+ /**
+ * Defines the type of calendar information that a client requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\FreeBusyViewType
+ */
+ public $RequestedView;
+
+ /**
+ * Identifies the time span queried for the user availability information.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\Duration
+ */
+ public $TimeWindow;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupAttendeeConflictData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupAttendeeConflictData.php
new file mode 100644
index 00000000..cd700472
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupAttendeeConflictData.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\GroupAttendeeConflictData.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents aggregate conflict information about the number of users who are
+ * available, the number of users who have conflicts, and the number of users
+ * who do not have availability information in a distribution list for a
+ * suggested meeting time.
+ *
+ * @package php-ews\Type
+ */
+class GroupAttendeeConflictData extends AttendeeConflictData
+{
+ /**
+ * Represents the number of users, resources, and rooms in a distribution
+ * list.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumberOfMembers;
+
+ /**
+ * Represents the number of distribution list members who are available for
+ * a suggested meeting time.
+ *
+ * This element represents members for whom the status is Free.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumberOfMembersAvailable;
+
+ /**
+ * Represents the number of distribution list members who have a conflict
+ * with a suggested meeting time.
+ *
+ * This element represents members who have a Busy, OOF, or Tentative status.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumberOfMembersWithConflict;
+
+ /**
+ * Represents the number of group members who do not have published
+ * free/busy data to compare to a suggested meeting time.
+ *
+ * This element represents members of a distribution list that is too large
+ * or members who have No Data status.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumberOfMembersWithNoData;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupByType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupByType.php
new file mode 100644
index 00000000..3835ff2e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupByType.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\GroupByType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an arbitrary grouping for FindItem queries.
+ *
+ * @package php-ews\Type
+ */
+class GroupByType extends BaseGroupByType
+{
+ /**
+ * Represents the field that is used to determine the order of groups in a
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AggregateOnType
+ */
+ public $AggregateOn;
+
+ /**
+ * Identifies extended MAPI properties to get, set, or create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType
+ */
+ public $ExtendedFieldURI;
+
+ /**
+ * Identifies frequently referenced properties by URI.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToUnindexedFieldType
+ */
+ public $FieldURI;
+
+ /**
+ * Identifies individual members of a dictionary.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToIndexedFieldType
+ */
+ public $IndexedFieldURI;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupedItemsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupedItemsType.php
new file mode 100644
index 00000000..e57668ba
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/GroupedItemsType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\GroupedItemsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a collection of items that are the result of a grouped FindItem
+ * operation call.
+ *
+ * @package php-ews\Type
+ */
+class GroupedItemsType extends Type
+{
+ /**
+ * Represents the property value that is used to group items in a grouped
+ * FindItem operation call.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $GroupIndex;
+
+ /**
+ * Contains an array of grouped items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRealItemsType
+ */
+ public $Items;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryEntryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryEntryType.php
new file mode 100644
index 00000000..0045afad
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryEntryType.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ImAddressDictionaryEntryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an instant messaging (IM) address for a contact.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a common EntryType class.
+ * @todo Create a common TextEntryType class.
+ */
+class ImAddressDictionaryEntryType extends Type
+{
+ /**
+ * Represents the IM address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $_;
+
+ /**
+ * Identifies the IM address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ImAddressKeyType
+ */
+ public $Key;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryType.php
new file mode 100644
index 00000000..952440b6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImAddressDictionaryType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ImAddressDictionaryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a collection of instant messaging addresses for a contact.
+ *
+ * @package php-ews\Type
+ */
+class ImAddressDictionaryType extends Type
+{
+ /**
+ * Represents an instant messaging address for a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ImAddressDictionaryEntryType
+ */
+ public $Entry;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImGroupType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImGroupType.php
new file mode 100644
index 00000000..baa5402f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImGroupType.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ImGroupType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an instant messaging group.
+ *
+ * @package php-ews\Type
+ */
+class ImGroupType extends Type
+{
+ /**
+ * Contains the display name of a new instant messaging group contact or
+ * the display name of a new instant messaging group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Specifies the instant messaging (IM) group identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ExchangeStoreId;
+
+ /**
+ * Specifies an array of additional properties
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfExtendedPropertyType
+ */
+ public $ExtendedProperties;
+
+ /**
+ * Specifies the group class of an instant messaging (IM) group.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $GroupType;
+
+ /**
+ * Specifies the identifiers of the contacts that are part of the instant
+ * messaging (IM) group.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemIdsType
+ */
+ public $MemberCorrelationKey;
+
+ /**
+ * Represents the Simple Mail Transfer Protocol (SMTP) address of an account
+ * to be used for impersonation or a Simple Mail Transfer Protocol (SMTP)
+ * recipient address of a calendar or contact sharing request.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImItemListType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImItemListType.php
new file mode 100644
index 00000000..49c2aca0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ImItemListType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ImItemListType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a list of instant messaging groups and instant messaging contacts.
+ *
+ * @package php-ews\Type
+ */
+class ImItemListType extends Type
+{
+ /**
+ * Represents an array of instant messaging (IM) groups.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfImGroupType
+ */
+ public $Groups;
+
+ /**
+ * Specifies an array of personas.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPeopleType
+ */
+ public $Personas;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndexedPageViewType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndexedPageViewType.php
new file mode 100644
index 00000000..7e3f58e1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndexedPageViewType.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IndexedPageViewType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes how paged conversation or item information is returned for a
+ * FindItem operation or FindConversation operation request.
+ *
+ * @package php-ews\Type
+ */
+class IndexedPageViewType extends BasePagingType
+{
+ /**
+ * Describes whether the page of items or conversations will start from the
+ * beginning or the end of the set of items or conversations that are found
+ * by using the search criteria.
+ *
+ * Seeking from the end always searches backward.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\IndexBasePointType
+ */
+ public $BasePoint;
+
+ /**
+ * Describes the offset from the BasePoint.
+ *
+ * If BasePoint is equal to Beginning, the offset is positive. If BasePoint
+ * is equal to End, the offset is handled as if it were negative. This
+ * identifies which item or conversation will be the first to be delivered
+ * in the response.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Offset;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndividualAttendeeConflictData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndividualAttendeeConflictData.php
new file mode 100644
index 00000000..37b308c5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IndividualAttendeeConflictData.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IndividualAttendeeConflictData.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a user's or contact's free/busy status for a time window that
+ * occurs at the same time as the suggested meeting time identified in the
+ * Suggestion element.
+ *
+ * @package php-ews\Type
+ */
+class IndividualAttendeeConflictData extends AttendeeConflictData
+{
+ /**
+ * Represents the free/busy status of a user for a suggested meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\LegacyFreeBusyType
+ */
+ public $BusyType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InstalledAppType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InstalledAppType.php
new file mode 100644
index 00000000..96d9c7fe
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InstalledAppType.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\InstalledAppType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Undocumented.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Update once documentation exists.
+ */
+class InstalledAppType extends Type
+{
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ConsentState;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Description;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $DisplayName;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var boolean
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Enabled;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $HighResolutionIconUrl;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $IconUrl;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Id;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $LicenseStatus;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $MarketplaceAssetId;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ProviderName;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Requirements;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ * @todo Make a DateTime object.
+ */
+ public $TrialExpirationDate;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Type;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Version;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InternetHeaderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InternetHeaderType.php
new file mode 100644
index 00000000..52b3f4e5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InternetHeaderType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\InternetHeaderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the Internet message header for a given header within a headers
+ * collection.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Extend a string class.
+ */
+class InternetHeaderType extends Type
+{
+ /**
+ * The value of the header.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $_;
+
+ /**
+ * Identifies the header name.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $HeaderName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IntervalRecurrencePatternBaseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IntervalRecurrencePatternBaseType.php
new file mode 100644
index 00000000..41c8b42a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IntervalRecurrencePatternBaseType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IntervalRecurrencePatternBaseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for recurrence patterns with an interval.
+ *
+ * @package php-ews\Type
+ */
+abstract class IntervalRecurrencePatternBaseType extends RecurrencePatternBaseType
+{
+ /**
+ * Defines the interval between two consecutive recurring pattern items.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Interval;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InvalidRecipientType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InvalidRecipientType.php
new file mode 100644
index 00000000..328aeb1e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/InvalidRecipientType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\InvalidRecipientType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the SMTP address of the invalid recipient and information about
+ * why the recipient is invalid.
+ *
+ * @package php-ews\Type
+ */
+class InvalidRecipientType extends Type
+{
+ /**
+ * Provides a text description of the status of the response.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $MessageText;
+
+ /**
+ * Provides an error code that identifies the specific error that the
+ * request encountered.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\InvalidRecipientResponseCodeType
+ */
+ public $ResponseCode;
+
+ /**
+ * Contains the SMTP address of the invalid recipient.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $SmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsEqualToType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsEqualToType.php
new file mode 100644
index 00000000..885d4457
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsEqualToType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IsEqualToType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and evaluates to true if they are equal.
+ *
+ * @package php-ews\Type
+ */
+class IsEqualToType extends TwoOperandExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanOrEqualToType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanOrEqualToType.php
new file mode 100644
index 00000000..8dac63b5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanOrEqualToType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IsGreaterThanOrEqualToType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property is
+ * greater than or equal to the second.
+ *
+ * @package php-ews\Type
+ */
+class IsGreaterThanOrEqualToType extends TwoOperandExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanType.php
new file mode 100644
index 00000000..785bc70c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsGreaterThanType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IsGreaterThanType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property is
+ * greater.
+ *
+ * @package php-ews\Type
+ */
+class IsGreaterThanType extends TwoOperandExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanOrEqualToType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanOrEqualToType.php
new file mode 100644
index 00000000..16f7d687
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanOrEqualToType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IsLessThanOrEqualToType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property is
+ * less than or equal to the second.
+ *
+ * @package php-ews\Type
+ */
+class IsLessThanOrEqualToType extends TwoOperandExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanType.php
new file mode 100644
index 00000000..14012353
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsLessThanType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IsLessThanType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property is
+ * less than the second.
+ *
+ * @package php-ews\Type
+ */
+class IsLessThanType extends TwoOperandExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsNotEqualToType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsNotEqualToType.php
new file mode 100644
index 00000000..dad615bd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/IsNotEqualToType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\IsNotEqualToType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property is
+ * less than or equal to the second.
+ *
+ * @package php-ews\Type
+ */
+class IsNotEqualToType extends TwoOperandExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemAttachmentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemAttachmentType.php
new file mode 100644
index 00000000..aba1725b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemAttachmentType.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ItemAttachmentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an Exchange item that is attached to another Exchange item.
+ *
+ * @package php-ews\Type
+ */
+class ItemAttachmentType extends AttachmentType
+{
+ /**
+ * Represents an Exchange calendar item attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarItemType
+ */
+ public $CalendarItem;
+
+ /**
+ * Represents an Exchange contact item attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactItemType
+ */
+ public $Contact;
+
+ /**
+ * Represents a generic Exchange item attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemType
+ */
+ public $Item;
+
+ /**
+ * Represents a meeting cancellation in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingCancellationMessageType
+ */
+ public $MeetingCancellation;
+
+ /**
+ * Represents a meeting in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingMessageType
+ */
+ public $MeetingMessage;
+
+ /**
+ * Represents a meeting request in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingRequestMessageType
+ */
+ public $MeetingRequest;
+
+ /**
+ * Represents a meeting response in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingResponseMessageType
+ */
+ public $MeetingResponse;
+
+ /**
+ * Represents an Exchange e-mail message attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MessageType
+ */
+ public $Message;
+
+ /**
+ * Represents a post item in the Exchange store.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostItemType
+ */
+ public $PostItem;
+
+ /**
+ * Represents an Exchange task attachment.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TaskType
+ */
+ public $Task;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeDescriptionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeDescriptionType.php
new file mode 100644
index 00000000..3f457273
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeDescriptionType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ItemChangeDescriptionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for changes to individual item properties.
+ *
+ * @package php-ews\Type
+ */
+class ItemChangeDescriptionType extends ChangeDescriptionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeType.php
new file mode 100644
index 00000000..e758cdf2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemChangeType.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ItemChangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an item identifier and the updates to apply to the item.
+ *
+ * @package php-ews\Type
+ */
+class ItemChangeType extends Type
+{
+ /**
+ * Contains the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * This element is required if the OccurrenceItemId or RecurringMasterItemId
+ * element is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Identifies a single occurrence of a recurring item.
+ *
+ * This element is required if used. This element is required if the
+ * RecurringMasterItemId or ItemId element is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\OccurrenceItemIdType
+ */
+ public $OccurrenceItemId;
+
+ /**
+ * Identifies a recurrence master item by identifying one of its related
+ * occurrence items' identifiers.
+ *
+ * This element is required if used. This element is required if the
+ * OccurrenceItemId or ItemId element is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurringMasterItemIdType
+ */
+ public $RecurringMasterItemId;
+
+ /**
+ * Contains an array that defines append, set, and delete changes to item
+ * properties.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfItemChangeDescriptionsType
+ */
+ public $Updates;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemIdType.php
new file mode 100644
index 00000000..0d549331
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemIdType.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ItemIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Contains the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * @package php-ews\Type
+ */
+class ItemIdType extends BaseItemIdType
+{
+ /**
+ * Identifies a specific version of an item.
+ *
+ * A ChangeKey is required for the following scenarios:
+ * - The UpdateItem element requires a ChangeKey if the ConflictResolution
+ * attribute is set to AutoResolve. AutoResolve is a default value. If the
+ * ChangeKey attribute is not included, the response will return a
+ * ResponseCode value equal to ErrorChangeKeyRequired.
+ * - The SendItem element requires a ChangeKey to test whether the attempted
+ * operation will act upon the most recent version of an item. If the
+ * ChangeKey attribute is not included in the ItemId or if the ChangeKey
+ * is empty, the response will return a ResponseCode value equal to
+ * ErrorStaleObject.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ChangeKey;
+
+ /**
+ * Identifies a specific item in the Exchange store.
+ *
+ * Id is case-sensitive; therefore, comparisons between Ids must be
+ * case-sensitive or binary.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Id;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemResponseShapeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemResponseShapeType.php
new file mode 100644
index 00000000..a48af464
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemResponseShapeType.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ItemResponseShapeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a set of properties to return in a GetItem operation, FindItem
+ * operation, or SyncFolderItems operation response.
+ *
+ * @package php-ews\Type
+ */
+class ItemResponseShapeType extends Type
+{
+ /**
+ * Identifies additional properties to return in a response.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType
+ */
+ public $AdditionalProperties;
+
+ /**
+ * Identifies the basic configuration of properties to return in an item or
+ * folder response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType
+ */
+ public $BaseShape;
+
+ /**
+ * Identifies how the body text is formatted in the response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\BodyTypeResponseType
+ */
+ public $BodyType;
+
+ /**
+ * Indicates whether the item HTML body is converted to UTF8.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $ConvertHtmlCodePageToUTF8;
+
+ /**
+ * Specifies whether HTML content filtering is enabled.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $FilterHtmlContent;
+
+ /**
+ * Specifies whether the Multipurpose Internet Mail Extensions (MIME)
+ * content of an item is returned in the response.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IncludeMimeContent;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemType.php
new file mode 100644
index 00000000..64c94034
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ItemType.php
@@ -0,0 +1,443 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a generic item in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class ItemType extends Type
+{
+ /**
+ * Contains the items or files that are attached to an item in the Exchange
+ * store.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttachmentsType
+ */
+ public $Attachments;
+
+ /**
+ * Represents the actual body content of a message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BodyType
+ */
+ public $Body;
+
+ /**
+ * Represents a collection of strings that identify the categories to which
+ * an item in the mailbox belongs.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Categories;
+
+ /**
+ * Contains the identifier of an item or conversation.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ConversationId;
+
+ /**
+ * Represents the culture for a given item in a mailbox.
+ *
+ * Specified by using the RFC 1766 culture identifier; for example, en-US.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Culture;
+
+ /**
+ * Represents the date and time that a given item in the mailbox was
+ * created.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $DateTimeCreated;
+
+ /**
+ * Represents the date and time that an item in a mailbox was received.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $DateTimeReceived;
+
+ /**
+ * Represents the date and time that an item in a mailbox was sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $DateTimeSent;
+
+ /**
+ * Represents the display string that is used for the contents of the Cc
+ * line.
+ *
+ * This is the concatenated string of all Cc recipient display names.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $DisplayCc;
+
+ /**
+ * Represents the display string that is used for the contents of the To
+ * line.
+ *
+ * This is the concatenated string of all To recipient display names.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $DisplayTo;
+
+ /**
+ * Contains the client's rights based on the permission settings for the
+ * item or folder.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EffectiveRightsType
+ */
+ public $EffectiveRights;
+
+ /**
+ * Identifies extended properties on folders and items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExtendedPropertyType[]
+ */
+ public $ExtendedProperty = array();
+
+ /**
+ * Represents a property that is set to true if an item has at least one
+ * visible attachment.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $HasAttachments;
+
+ /**
+ * Describes the importance of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ImportanceChoicesType
+ */
+ public $Importance;
+
+ /**
+ * Represents the identifier of the item to which this item is a reply.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $InReplyTo;
+
+ /**
+ * Represents the collection of all Internet message headers that are
+ * contained in an item in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfInternetHeadersType
+ */
+ public $InternetMessageHeaders;
+
+ /**
+ * Indicates whether the item is associated with a folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsAssociated;
+
+ /**
+ * Indicates whether an item has not yet been sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsDraft;
+
+ /**
+ * Indicates whether a user sent an item to him or herself.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsFromMe;
+
+ /**
+ * Indicates whether the item had previously been sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsResend;
+
+ /**
+ * Indicates whether an item has been submitted to the Outbox default
+ * folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsSubmitted;
+
+ /**
+ * Indicates whether the item has been modified.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsUnmodified;
+
+ /**
+ * Represents the message class of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ItemClassType
+ */
+ public $ItemClass;
+
+ /**
+ * Contains the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Contains the display name of the last user to modify an item.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $LastModifiedName;
+
+ /**
+ * Indicates when an item was last modified.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $LastModifiedTime;
+
+ /**
+ * Contains the native Multipurpose Internet Mail Extensions (MIME) stream
+ * of an object that is represented in base64Binary format.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MimeContentType
+ */
+ public $MimeContent;
+
+ /**
+ * Represents the identifier of the parent folder that contains the item or
+ * folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $ParentFolderId;
+
+ /**
+ * Identifies the delegate in a delegate access scenario.
+ *
+ * @since Exchange 2007 SP1
+ * @deprecated Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $ReceivedBy;
+
+ /**
+ * Identifies the principal in a delegate access scenario.
+ *
+ * @since Exchange 2007 SP1
+ * @deprecated Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $ReceivedRepresenting;
+
+ /**
+ * Represents the date and time when the event occurs.
+ *
+ * This is used by the ReminderMinutesBeforeStart element to determine when
+ * the reminder is displayed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $ReminderDueBy;
+
+ /**
+ * Indicates whether a reminder has been set for an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $ReminderIsSet;
+
+ /**
+ * Represents the number of minutes before an event when a reminder is
+ * displayed.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ *
+ * @todo Determine if we need a ReminderMinutesBeforeStartType
+ * implementation.
+ */
+ public $ReminderMinutesBeforeStart;
+
+ /**
+ * Contains a collection of all the response objects that are associated
+ * with an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfResponseObjectsType
+ */
+ public $ResponseObjects;
+
+ /**
+ * Indicates the sensitivity level of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SensitivityChoicesType
+ */
+ public $Sensitivity;
+
+ /**
+ * Represents the size in bytes of an item.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Size;
+
+ /**
+ * Exchange store identifier of an item.
+ *
+ * @since Exchange 2010 SP2
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $StoreEntryId;
+
+ /**
+ * Represents the subject for Exchange store items and response objects.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Subject;
+
+ /**
+ * Represents an HTML fragment or plain text which represents the unique
+ * body of this conversation.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\BodyType
+ */
+ public $UniqueBody;
+
+ /**
+ * Represents a URL to concatenate to the Microsoft Office Outlook Web App
+ * endpoint to edit an item in Outlook Web App.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $WebClientEditFormQueryString;
+
+ /**
+ * Represents a URL to concatenate to the Microsoft Office Outlook Web App
+ * endpoint to read an item in Outlook Web App.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $WebClientReadFormQueryString;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/KeywordStatisticsSearchResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/KeywordStatisticsSearchResultType.php
new file mode 100644
index 00000000..00a58226
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/KeywordStatisticsSearchResultType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\KeywordStatisticsSearchResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single keyword search result.
+ *
+ * @package php-ews\Type
+ */
+class KeywordStatisticsSearchResultType extends Type
+{
+ /**
+ * Identifies how many times a keyword was found.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $ItemHits;
+
+ /**
+ * Specifies a single keyword.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Keyword;
+
+ /**
+ * Defines the total size of one or more mailbox items.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $Size;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTips.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTips.php
new file mode 100644
index 00000000..3c4096ba
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTips.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailTips.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents values for various types of mail tips.
+ *
+ * @package php-ews\Type
+ */
+class MailTips extends Type
+{
+ /**
+ * Represents a customized mail tip message.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $CustomMailTip;
+
+ /**
+ * Indicates whether delivery restrictions will prevent the sender’s message
+ * from reaching the recipient.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $DeliveryRestricted;
+
+ /**
+ * Represents the count of external members in a group.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $ExternalMemberCount;
+
+ /**
+ * Indicates whether the recipient is invalid.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $InvalidRecipient;
+
+ /**
+ * Indicates whether the recipient's mailbox is being moderated.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsModerated;
+
+ /**
+ * Indicates whether the mailbox for the recipient is full.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $MailboxFull;
+
+ /**
+ * Represents the maximum message size the recipient can accept.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $MaxMessageSize;
+
+ /**
+ * Represents the response message and a duration time for sending the
+ * response message.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\OutOfOfficeMailTip
+ */
+ public $OutOfOffice;
+
+ /**
+ * Indicates that the mail tips in this element could not be evaluated
+ * before the server's processing timeout expired.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MailTipTypes
+ */
+ public $PendingMailTips;
+
+ /**
+ * Represents the mailbox of the recipient.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $RecipientAddress;
+
+ /**
+ * Represents the count of all members in a group.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $TotalMemberCount;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTipsServiceConfiguration.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTipsServiceConfiguration.php
new file mode 100644
index 00000000..bcef3440
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailTipsServiceConfiguration.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailTipsServiceConfiguration.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents service configuration information for the mail tips service.
+ *
+ * @package php-ews\Type
+ */
+class MailTipsServiceConfiguration extends ServiceConfiguration
+{
+ /**
+ * Identifies the list of internal SMTP domains of the organization.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\SmtpDomainList
+ */
+ public $InternalDomains;
+
+ /**
+ * Represents the large audience threshold for a client.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $LargeAudienceThreshold;
+
+ /**
+ * Indicates whether the mail tips service is available.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $MailTipsEnabled;
+
+ /**
+ * Represents the maximum message size a recipient can accept.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $MaxMessageSize;
+
+ /**
+ * Indicates the maximum number of recipients that can be passed to the
+ * GetMailTips operation.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $MaxRecipientsPerGetMailTipsRequest;
+
+ /**
+ * Indicates whether consumers of the GetMailTips operation have to show
+ * mail tips that indicate the number of external recipients to which a
+ * message is addressed.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $ShowExternalRecipientCount;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxData.php
new file mode 100644
index 00000000..8ff96784
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxData.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailboxData.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an individual mailbox user and options for the type of data to be
+ * returned about the mailbox user.
+ *
+ * @package php-ews\Type
+ */
+class MailboxData extends Type
+{
+ /**
+ * Represents the type of attendee identified in the Email property.
+ *
+ * This is used in requests for meeting suggestions.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MeetingAttendeeType
+ */
+ public $AttendeeType;
+
+ /**
+ * Represents the mailbox user for a GetUserAvailability query.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Email;
+
+ /**
+ * Specifies whether to return suggested times for calendar times that
+ * conflict among the attendees.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $ExcludeConflicts;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldResultType.php
new file mode 100644
index 00000000..5dddbfa6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldResultType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailboxHoldResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the result of the mailbox hold request request.
+ *
+ * @package php-ews\Type
+ */
+class MailboxHoldResultType extends Type
+{
+ /**
+ * Contains the mailbox hold identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $HoldId;
+
+ /**
+ * Specifies a list of one or more mailbox hold statuses.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfMailboxHoldStatusType
+ */
+ public $MailboxHoldStatuses;
+
+ /**
+ * Contains the search query for the hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Query;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldStatusType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldStatusType.php
new file mode 100644
index 00000000..3304dd50
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxHoldStatusType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailboxHoldStatusType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the hold status of a mailbox.
+ *
+ * @package php-ews\Type
+ */
+class MailboxHoldStatusType extends Type
+{
+ /**
+ * Specifies additional information about the hold status of a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $AdditionalInfo;
+
+ /**
+ * Contains the identifier for a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Mailbox;
+
+ /**
+ * Specifies the hold status for a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\HoldStatusType
+ */
+ public $Status;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxQueryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxQueryType.php
new file mode 100644
index 00000000..8411c6af
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxQueryType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailboxQueryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a query and the scope of a discovery search.
+ *
+ * @package php-ews\Type
+ */
+class MailboxQueryType extends Type
+{
+ /**
+ * Specifies a list of one or more mailboxes and associated search scopes
+ * for a discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfMailboxSearchScopesType
+ */
+ public $MailboxSearchScopes;
+
+ /**
+ * Contains the search query for the hold.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Query;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxSearchScopeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxSearchScopeType.php
new file mode 100644
index 00000000..fc8be21b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxSearchScopeType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailboxSearchScopeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a mailbox and a search scope for a discovery search.
+ *
+ * @package php-ews\Type
+ */
+class MailboxSearchScopeType extends Type
+{
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfExtendedAttributesType
+ */
+ public $ExtendedAttributes;
+
+ /**
+ * Contains an identifier for a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Mailbox;
+
+ /**
+ * Specifies a mailbox and a search scope for a discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MailboxSearchLocationType
+ */
+ public $SearchScope;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxStatisticsSearchResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxStatisticsSearchResultType.php
new file mode 100644
index 00000000..eccb1b9f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MailboxStatisticsSearchResultType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MailboxStatisticsSearchResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the results of a keyword search.
+ *
+ * @package php-ews\Type
+ */
+class MailboxStatisticsSearchResultType extends Type
+{
+ /**
+ * Contains a single keyword search result.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\KeywordStatisticsSearchResultType
+ */
+ public $KeywordStatisticsSearchResult;
+
+ /**
+ * Identifies the user's mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserMailboxType
+ */
+ public $UserMailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ManagedFolderInformationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ManagedFolderInformationType.php
new file mode 100644
index 00000000..fd0468f8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ManagedFolderInformationType.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ManagedFolderInformationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Compound property for Managed Folder related information for Managed Folders.
+ *
+ * @package php-ews\Type
+ */
+class ManagedFolderInformationType extends Type
+{
+ /**
+ * Indicates whether a managed folder can be deleted by a customer.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $CanDelete;
+
+ /**
+ * Indicates whether a given managed folder can be renamed or moved by the
+ * customer.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $CanRenameOrMove;
+
+ /**
+ * Contains the comment that is associated with a managed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Comment;
+
+ /**
+ * Describes the total size of all the contents of a managed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $FolderSize;
+
+ /**
+ * Indicates whether the managed folder has a quota.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $HasQuota;
+
+ /**
+ * Specifies the URL that will be the default home page for the managed
+ * folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $HomePage;
+
+ /**
+ * Indicates whether the managed folder is the root for all managed folders.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsManagedFoldersRoot;
+
+ /**
+ * Contains the folder ID of the managed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ManagedFolderId;
+
+ /**
+ * Indicates whether the managed folder comment must be displayed.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $MustDisplayComment;
+
+ /**
+ * Describes the storage quota for the managed folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $StorageQuota;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingCancellationMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingCancellationMessageType.php
new file mode 100644
index 00000000..caa7f5a2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingCancellationMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MeetingCancellationMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a meeting cancellation in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class MeetingCancellationMessageType extends MeetingMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingMessageType.php
new file mode 100644
index 00000000..60f419b6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingMessageType.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MeetingMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a meeting in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class MeetingMessageType extends MessageType
+{
+ /**
+ * Represents the calendar item that is associated with a MeetingMessage.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $AssociatedCalendarItemId;
+
+ /**
+ * Indicates the date and time that an instance of an iCalendar object was
+ * created.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $DateTimeStamp;
+
+ /**
+ * Indicates whether a meeting message item has been processed.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $HasBeenProcessed;
+
+ /**
+ * Indicates whether a meeting was handled by an account with delegate
+ * access.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsDelegated;
+
+ /**
+ * Indicates whether a meeting message is out-of-date.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsOutOfDate;
+
+ /**
+ * Used to identify a specific instance of a recurring calendar item.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $RecurrenceId;
+
+ /**
+ * Represents the type of recipient response received for a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ResponseTypeType
+ */
+ public $ResponseType;
+
+ /**
+ * Identifies a calendar item.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $UID;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingRequestMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingRequestMessageType.php
new file mode 100644
index 00000000..8dd888b6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingRequestMessageType.php
@@ -0,0 +1,423 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MeetingRequestMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a meeting cancellation in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class MeetingRequestMessageType extends MeetingMessageType
+{
+ /**
+ * Represents the total number of calendar items that are adjacent to a
+ * meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AdjacentMeetingCount;
+
+ /**
+ * Describes all calendar items that are adjacent to a meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType
+ */
+ public $AdjacentMeetings;
+
+ /**
+ * Represents whether a new meeting time can be proposed for a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $AllowNewTimeProposal;
+
+ /**
+ * Represents the date and time when an attendee replied to a meeting
+ * request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $AppointmentReplyTime;
+
+ /**
+ * Specifies the sequence number of a version of an appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AppointmentSequenceNumber;
+
+ /**
+ * Specifies the status of the appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $AppointmentState;
+
+ /**
+ * Represents the occurrence type of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CalendarItemTypeType
+ */
+ public $CalendarItemType;
+
+ /**
+ * Describes the type of conferencing that is performed with a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConferenceType
+ */
+ public $ConferenceType;
+
+ /**
+ * Represents the number of meetings that conflict with the meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $ConflictingMeetingCount;
+
+ /**
+ * Identifies all items that conflict with a meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType
+ */
+ public $ConflictingMeetings;
+
+ /**
+ * Contains an array of deleted occurrences of a recurring calendar item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfDeletedOccurrencesType
+ */
+ public $DeletedOccurrences;
+
+ /**
+ * Represents the duration of a calendar item.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Duration;
+
+ /**
+ * Represents the end of a duration.
+ *
+ * This element only applies to a single occurrence of a calendar item.
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $End;
+
+ /**
+ * Represents the end time zone of the calendar item.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType
+ */
+ public $EndTimeZone;
+
+ /**
+ * Represents the first occurrence of a recurring calendar item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\OccurrenceInfoType
+ */
+ public $FirstOccurrence;
+
+ /**
+ * Represents the intended status for the calendar item that is associated
+ * with the meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\LegacyFreeBusyType
+ */
+ public $IntendedFreeBusyStatus;
+
+ /**
+ * Indicates whether a calendar item or meeting request represents an
+ * all-day event.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsAllDayEvent;
+
+ /**
+ * Indicates whether an appointment or meeting has been cancelled.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsCancelled;
+
+ /**
+ * Indicates whether the calendar item is either a meeting or appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsMeeting;
+
+ /**
+ * Indicates whether the meeting is online.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsOnlineMeeting;
+
+ /**
+ * Indicates whether a calendar item is part of a recurring item.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsRecurring;
+
+ /**
+ * Represents the last occurrence of a recurring calendar item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\OccurrenceInfoType
+ */
+ public $LastOccurrence;
+
+ /**
+ * Represents the free/busy status of the calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\LegacyFreeBusyType
+ */
+ public $LegacyFreeBusyStatus;
+
+ /**
+ * Represents the location of a meeting or appointment.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Location;
+
+ /**
+ * Describes the type of the meeting request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MeetingRequestTypeType
+ */
+ public $MeetingRequestType;
+
+ /**
+ * Indicates whether a meeting request has been sent to requested attendees.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $MeetingRequestWasSent;
+
+ /**
+ * Represents the time zone of the location where the meeting is hosted.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneType
+ */
+ public $MeetingTimeZone;
+
+ /**
+ * Contains the URL for the meeting workspace that is linked to by the
+ * calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $MeetingWorkspaceUrl;
+
+ /**
+ * Contains an array of recurring calendar item occurrences that have been
+ * modified so that they are different than the recurrence master item.
+ *
+ * This element is valid if CalendarItemType has the RecurringMaster value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfOccurrenceInfoType
+ */
+ public $ModifiedOccurrences;
+
+ /**
+ * Contains the status of or response to a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ResponseTypeType
+ */
+ public $MyResponseType;
+
+ /**
+ * Specifies the URL for a Microsoft Netshow online meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $NetShowUrl;
+
+ /**
+ * Represents attendees that are not required to attend a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttendeesType
+ */
+ public $OptionalAttendees;
+
+ /**
+ * Represents the organizer of a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $Organizer;
+
+ /**
+ * Represents the original start time of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $OriginalStart;
+
+ /**
+ * Contains the recurrence pattern for calendar items and meeting requests.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurrenceType
+ */
+ public $Recurrence;
+
+ /**
+ * Represents attendees that are required to attend a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttendeesType
+ */
+ public $RequiredAttendees;
+
+ /**
+ * Represents a scheduled resource for a meeting.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttendeesType
+ */
+ public $Resources;
+
+ /**
+ * Represents the start of a calendar item.
+ *
+ * This element only applies to a single occurrence of a calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Start;
+
+ /**
+ * Represents the start time zone of the calendar item.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType
+ */
+ public $StartTimeZone;
+
+ /**
+ * Provides a text description of a time zone.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $TimeZone;
+
+ /**
+ * Provides a description of when a meeting occurs.
+ *
+ * @since Exchange 2007
+ *
+ * @type string
+ */
+ public $When;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingResponseMessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingResponseMessageType.php
new file mode 100644
index 00000000..651aa4ec
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MeetingResponseMessageType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MeetingResponseMessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a meeting response in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class MeetingResponseMessageType extends MeetingMessageType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MemberType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MemberType.php
new file mode 100644
index 00000000..1a17defe
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MemberType.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MemberType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a member of a distribution list.
+ *
+ * @package php-ews\Type
+ */
+class MemberType extends Type
+{
+ /**
+ * Provides a unique identifier for the distribution list member.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Key;
+
+ /**
+ * Represents the e-mail address of the distribution list member.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+
+ /**
+ * Provides information about the status of a distribution list member.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MemberStatusType
+ */
+ public $Status;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MembersListType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MembersListType.php
new file mode 100644
index 00000000..645643f1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MembersListType.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MembersListType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the list of members for a distribution list.
+ *
+ * @package php-ews\Type
+ */
+class MembersListType extends Type
+{
+ /**
+ * Provides an identifier for a fully resolved e-mail address, and the
+ * status of that address on the server.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\MemberType[]
+ */
+ public $Member = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageTrackingReportType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageTrackingReportType.php
new file mode 100644
index 00000000..21a0b9a6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageTrackingReportType.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MessageTrackingReportType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single message that is returned in a GetMessageTrackingReport
+ * operation.
+ *
+ * @package php-ews\Type
+ */
+class MessageTrackingReportType extends Type
+{
+ /**
+ * Contains a list of the recipients of the e-mail message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $OriginalRecipients;
+
+ /**
+ * Contains a list of one or more tracking properties.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType
+ */
+ public $Properties;
+
+ /**
+ * Contains contact information for the alleged sender of an e-mail message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $PurportedSender;
+
+ /**
+ * Contains a list of one or more tracking events for the recipients.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientTrackingEventType
+ */
+ public $RecipientTrackingEvents;
+
+ /**
+ * Contains contact information for the sender of the e-mail message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Sender;
+
+ /**
+ * Contains the subject of the e-mail message.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $Subject;
+
+ /**
+ * Contains the time of day that the e-mail message was submitted.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $SubmitTime;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageType.php
new file mode 100644
index 00000000..b4b306d5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MessageType.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MessageType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a Microsoft Exchange e-mail message.
+ *
+ * @package php-ews\Type
+ */
+class MessageType extends ItemType
+{
+ /**
+ * Represents a collection of recipients to receive a blind carbon copy
+ * (Bcc) of an e-mail.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $BccRecipients;
+
+ /**
+ * Represents a collection of recipients that will receive a copy of the
+ * message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $CcRecipients;
+
+ /**
+ * Contains a binary ID that represents the thread to which this message
+ * belongs.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a base 64 class?
+ */
+ public $ConversationIndex;
+
+ /**
+ * Represents the conversation identifier.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ConversationTopic;
+
+ /**
+ * Represents the addressee from whom the message was sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $From;
+
+ /**
+ * Represents the Internet message identifier of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $InternetMessageId;
+
+ /**
+ * Indicates whether the sender of an item requests a delivery receipt.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsDeliveryReceiptRequested;
+
+ /**
+ * Indicates whether a message has been read.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsRead;
+
+ /**
+ * Indicates whether the sender of an item requests a read receipt.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsReadReceiptRequested;
+
+ /**
+ * Indicates whether a response to an e-mail message is requested.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsResponseRequested;
+
+ /**
+ * Represents the Usenet header that is used to correlate replies with their
+ * original messages.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $References;
+
+ /**
+ * Identifies a set of addresses to which replies should be sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $ReplyTo;
+
+ /**
+ * Identifies the sender of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SensitivityChoicesType
+ */
+ public $Sender;
+
+ /**
+ * Contains a set of recipients of a message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $ToRecipients;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MimeContentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MimeContentType.php
new file mode 100644
index 00000000..733c2202
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MimeContentType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MimeContentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the native Multipurpose Internet Mail Extensions (MIME) stream of
+ * an object that is represented in base64Binary format.
+ *
+ * @package php-ews\Type
+ */
+class MimeContentType extends Type
+{
+ /**
+ * A text value that represents a base64Binary MIME stream.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $_;
+
+ /**
+ * The International Standards Organization (ISO) name of the character set
+ * used in the MIME message.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $CharacterSet;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ModifiedEventType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ModifiedEventType.php
new file mode 100644
index 00000000..c2ba0a7a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ModifiedEventType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ModifiedEventType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an event in which an item or folder is modified.
+ *
+ * @package php-ews\Type
+ */
+class ModifiedEventType extends BaseObjectChangedEventType
+{
+ /**
+ * Represents the count of unread items within a given folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $UnreadCount;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MonthlyRegeneratingPatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MonthlyRegeneratingPatternType.php
new file mode 100644
index 00000000..22a0f57b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MonthlyRegeneratingPatternType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MonthlyRegeneratingPatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the frequency, in months, of which task is regenerated.
+ *
+ * @package php-ews\Type
+ */
+class MonthlyRegeneratingPatternType extends RegeneratingPatternBaseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MovedCopiedEventType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MovedCopiedEventType.php
new file mode 100644
index 00000000..66d4ede8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MovedCopiedEventType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MovedCopiedEventType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an event in which an item or folder is copied.
+ *
+ * @package php-ews\Type
+ */
+class MovedCopiedEventType extends BaseObjectChangedEventType
+{
+ /**
+ * Represents the folder identifier of the original folder before it was
+ * copied.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $OldFolderId;
+
+ /**
+ * Contains the unique identifier of the original item before it was copied.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $OldItemId;
+
+ /**
+ * Contains the identifier of the original parent folder of an item or
+ * folder that was copied.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $OldParentFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MultipleOperandBooleanExpressionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MultipleOperandBooleanExpressionType.php
new file mode 100644
index 00000000..3bb2f1d6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/MultipleOperandBooleanExpressionType.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\MultipleOperandBooleanExpressionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for derived elements that represent a restriction formed by two or
+ * more Boolean operands.
+ *
+ * @package php-ews\Type
+ */
+abstract class MultipleOperandBooleanExpressionType extends Type
+{
+ /**
+ * Represents a search expression that enables you to perform a Boolean AND
+ * operation between two or more search expressions.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AndType
+ */
+ public $And;
+
+ /**
+ * Represents a search expression that determines whether a given property
+ * contains the supplied constant string value.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContainsExpressionType
+ */
+ public $Contains;
+
+ /**
+ * Performs a bitwise mask of the properties.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExcludesType
+ */
+ public $Excludes;
+
+ /**
+ * Represents a search expression that returns true if the supplied property
+ * exists on an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ExistsType
+ */
+ public $Exists;
+
+ /**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and evaluates to true if they are
+ * equal.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IsEqualToType
+ */
+ public $IsEqualTo;
+
+ /**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property
+ * is greater than the value or property.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IsGreaterThanType
+ */
+ public $IsGreaterThan;
+
+ /**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property
+ * is greater than or equal to the value or property.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IsGreaterThanOrEqualToType
+ */
+ public $IsGreaterThanOrEqualTo;
+
+ /**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property
+ * is less than the value or property.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IsLessThanType
+ */
+ public $IsLessThan;
+
+ /**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the first property
+ * is less than or equal to the value or property.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IsLessThanOrEqualToType
+ */
+ public $IsLessThanOrEqualTo;
+
+ /**
+ * Represents a search expression that compares a property with either a
+ * constant value or another property and returns true if the values are not
+ * the same.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\IsNotEqualToType
+ */
+ public $IsNotEqualTo;
+
+ /**
+ * Represents a search expression that negates the Boolean value of the
+ * search expression it contains.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\NotType
+ */
+ public $Not;
+
+ /**
+ * Represents a search expression that performs a logical OR operation on
+ * the search expression it contains. The Or element will return true if any
+ * of its children return true.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\OrType
+ */
+ public $Or;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NoEndRecurrenceRangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NoEndRecurrenceRangeType.php
new file mode 100644
index 00000000..59426aab
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NoEndRecurrenceRangeType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\NoEndRecurrenceRangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the start date of an item recurrence pattern that does not have a
+ * defined end date.
+ *
+ * @package php-ews\Type
+ */
+class NoEndRecurrenceRangeType extends RecurrenceRangeBaseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailResultType.php
new file mode 100644
index 00000000..8a9ace5f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailResultType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\ArrayType\NonIndexableItemDetailResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the results of the GetNonIndexableItemDetails request.
+ *
+ * @package php-ews\Type
+ */
+class NonIndexableItemDetailResultType extends Type
+{
+ /**
+ * Specifies an array of mailboxes that failed on search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFailedSearchMailboxesType
+ */
+ public $FailedMailboxes;
+
+ /**
+ * Contains an array of item details for non-indexable items.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfNonIndexableItemDetailsType
+ */
+ public $Items;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailType.php
new file mode 100644
index 00000000..cfc977de
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemDetailType.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\NonIndexableItemDetailType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines detail information about an item that cannot be indexed.
+ *
+ * @package php-ews\Type
+ */
+class NonIndexableItemDetailType extends Type
+{
+ /**
+ * Contains the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Internal use only.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ErrorCode;
+
+ /**
+ * Describes the error that is returned in information about an item that
+ * cannot be indexed.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ErrorDescription;
+
+ /**
+ * Indicates whether the item is partially indexed.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsPartiallyIndexed;
+
+ /**
+ * Indicates whether a previous attempt to index the item was unsuccessful.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsPermanentFailure;
+
+ /**
+ * Specifies a value used for sorting.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SortValue;
+
+ /**
+ * Represents the number of attempts that have been made to index the item.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $AttemptCount;
+
+ /**
+ * Contains the time and date at which the last attempt to index the item
+ * was made.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $LastAttemptTime;
+
+ /**
+ * Specifies additional information about the hold status of a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $AdditionalInfo;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemStatisticType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemStatisticType.php
new file mode 100644
index 00000000..f29b1da2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NonIndexableItemStatisticType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\NonIndexableItemStatisticType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a single statistic for an item that could not be indexed.
+ *
+ * @package php-ews\Type
+ */
+class NonIndexableItemStatisticType extends Type
+{
+ /**
+ * Represents the reason for the validation error.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ErrorMessage;
+
+ /**
+ * Specifies the total number of items in a search result.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $ItemCount;
+
+ /**
+ * Contains an identifier for a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotType.php
new file mode 100644
index 00000000..e4811ee3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\NotType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that negates the Boolean value of the search
+ * expression that it contains.
+ *
+ * @package php-ews\Type
+ */
+class NotType extends MultipleOperandBooleanExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotificationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotificationType.php
new file mode 100644
index 00000000..fa677fd9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NotificationType.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\NotificationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Contains information about the subscription and the events that have occurred
+ * since the last notification.
+ *
+ * @package php-ews\Type
+ */
+class NotificationType extends Type
+{
+ /**
+ * Represents an event in which an item or folder is copied.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MovedCopiedEventType
+ */
+ public $CopiedEvent;
+
+ /**
+ * Represents an event in which an item or folder is created.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BaseObjectChangedEventType
+ */
+ public $CreatedEvent;
+
+ /**
+ * Represents an event in which an item or folder is deleted.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BaseObjectChangedEventType
+ */
+ public $DeletedEvent;
+
+ /**
+ * Represents an event in which an item’s free/busy time has changed.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\BaseObjectChangedEventType
+ */
+ public $FreeBusyChangedEvent;
+
+ /**
+ * Represents an event in which an item or folder is modified.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ModifiedEventType
+ */
+ public $ModifiedEvent;
+
+ /**
+ * Indicates whether there are more events in the queue to be delivered to
+ * the client.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $MoreEvents;
+
+ /**
+ * Represents an event in which an item or folder is moved from one parent
+ * folder to another parent folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MovedCopiedEventType
+ */
+ public $MovedEvent;
+
+ /**
+ * Represents an event that is triggered by a new mail item in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BaseObjectChangedEventType
+ */
+ public $NewMailEvent;
+
+ /**
+ * Represents the watermark of the latest event that was successfully
+ * communicated to the client for the subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PreviousWatermark;
+
+ /**
+ * Represents a notification that no new activity has occurred in the
+ * mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BaseNotificationEventType
+ */
+ public $StatusEvent;
+
+ /**
+ * Represents the identifier for a subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SubscriptionId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NumberedRecurrenceRangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NumberedRecurrenceRangeType.php
new file mode 100644
index 00000000..d3358a10
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/NumberedRecurrenceRangeType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\NumberedRecurrenceRangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the start date and the number of occurrences of a recurring item.
+ *
+ * @package php-ews\Type
+ */
+class NumberedRecurrenceRangeType extends RecurrenceRangeBaseType
+{
+ /**
+ * Contains the number of occurrences of a recurring item.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $NumberOfOccurrences;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceInfoType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceInfoType.php
new file mode 100644
index 00000000..3b628d0a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceInfoType.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\OccurrenceInfoType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an occurrence of a recurring calendar item.
+ *
+ * @package php-ews\Type
+ */
+class OccurrenceInfoType extends Type
+{
+ /**
+ * Represents the end time of the first occurrence of a recurring calendar
+ * item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $End;
+
+ /**
+ * Contains the unique identifier and change key of the first occurrence of
+ * a recurring calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Represents the original start time of the first occurrence of a recurring
+ * calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $OriginalStart;
+
+ /**
+ * Represents the start time of the first occurrence of a recurring calendar
+ * item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Start;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceItemIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceItemIdType.php
new file mode 100644
index 00000000..48a6fabb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrenceItemIdType.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\OccurrenceItemIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a single occurrence of a recurring item.
+ *
+ * @package php-ews\Type
+ */
+class OccurrenceItemIdType extends BaseItemIdType
+{
+ /**
+ * Identifies a specific version of the recurring master or an item
+ * occurrence.
+ *
+ * If either the recurring master or any of its occurrences change, the
+ * changeKey changes. The ChangeKey is the same for the recurring master and
+ * all occurrences.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ChangeKey;
+
+ /**
+ * Identifies the index of the item occurrence.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $InstanceIndex;
+
+ /**
+ * Identifies the recurring master of a recurring item.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $RecurringMasterId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrencesRangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrencesRangeType.php
new file mode 100644
index 00000000..7bac819e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OccurrencesRangeType.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\OccurrencesRangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a range of calendar item occurrences for a repeating calendar item.
+ *
+ * @package php-ews\Type
+ */
+class OccurrencesRangeType extends Type
+{
+ /**
+ * Start date of the recurring item range.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Start;
+
+ /**
+ * End date of the recurring item range.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $End;
+
+ /**
+ * Number of occurrences of the recurring item.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $Count;
+
+ /**
+ * Whether or not the client should compare the original start time with the
+ * new start time.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $CompareOriginalStartTime;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OpenAsAdminOrSystemServiceType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OpenAsAdminOrSystemServiceType.php
new file mode 100644
index 00000000..9fb13ba3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OpenAsAdminOrSystemServiceType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\OpenAsAdminOrSystemServiceType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * For internal use only. Not used by clients.
+ *
+ * @package php-ews\Type
+ */
+class OpenAsAdminOrSystemServiceType extends Type
+{
+ /**
+ * Not intended for client use.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $ConnectingSID;
+
+ /**
+ * Not intended for client use.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $LogonType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OrType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OrType.php
new file mode 100644
index 00000000..ff586f42
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OrType.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\OrType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search expression that performs a logical OR on the search
+ * expression that it contains.
+ *
+ * Or will return true if any of its children return true. Or must have two or
+ * more children.
+ *
+ * @package php-ews\Type
+ */
+class OrType extends MultipleOperandBooleanExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OutOfOfficeMailTip.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OutOfOfficeMailTip.php
new file mode 100644
index 00000000..33ec45b5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/OutOfOfficeMailTip.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\OutOfOfficeMailTip.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the response message and a duration time for sending the response
+ * message.
+ *
+ * @package php-ews\Type
+ */
+class OutOfOfficeMailTip extends Type
+{
+ /**
+ * Contains the duration that the OOF status is enabled if the OofState
+ * element is set to Scheduled.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\Duration
+ */
+ public $Duration;
+
+ /**
+ * Contains an Out of Office (OOF) message and the language used for the
+ * message.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReplyBody
+ */
+ public $ReplyBody;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToExtendedFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToExtendedFieldType.php
new file mode 100644
index 00000000..061d65da
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToExtendedFieldType.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PathToExtendedFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an extended property.
+ *
+ * Note that there are only a couple of valid attribute combinations. Note that
+ * all occurrences require the PropertyType attribute.
+ *
+ * 1. (DistinguishedPropertySetId || PropertySetId) +
+ * (PropertyName || Property Id)
+ * 2. PropertyTag
+ *
+ * @package php-ews\Type
+ */
+class PathToExtendedFieldType extends BasePathToElementType
+{
+ /**
+ * Defines the well-known property set IDs for extended MAPI properties.
+ *
+ * If this attribute is used, the PropertySetId and PropertyTag attributes
+ * cannot be used. This attribute must be used with either the PropertyId or
+ * PropertyName attribute, and the PropertyType attribute.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DistinguishedPropertySetType
+ */
+ public $DistinguishedPropertySetId;
+
+ /**
+ * Identifies an extended property by its dispatch ID.
+ *
+ * The dispatch ID can be identified in either decimal or hexadecimal
+ * formats. This property must be coupled with either
+ * DistinguishedPropertySetId or PropertySetId. If this attribute is used,
+ * the PropertyName and PropertyTag attributes cannot be used.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PropertyId;
+
+ /**
+ * Identifies an extended property by its name.
+ *
+ * This property must be coupled with either DistinguishedPropertySetId or
+ * PropertySetId. If this attribute is used, the PropertyId and PropertyTag
+ * attributes cannot be used.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PropertyName;
+
+ /**
+ * Identifies a MAPI extended property set or namespace by its identifying
+ * GUID.
+ *
+ * If this attribute is used, the DistinguishedPropertySetId and PropertyTag
+ * attribute cannot be used. This attribute must be used with either the
+ * PropertyId or PropertyName attribute, and the PropertyType attribute.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PropertySetId;
+
+ /**
+ * Identifies the property tag without the type part of the tag.
+ *
+ * The PropertyTag can be represented as either a hexadecimal or a short
+ * integer. The range between 0x8000 and 0xFFFE represents the custom range
+ * of properties. When a mailbox database encounters a custom property for
+ * the first time, it assigns that custom property a property tag within the
+ * custom property range of 0x8000-0xFFFE. A given custom property tag will
+ * most likely differ across databases. Therefore, a custom property request
+ * by property tag can return different properties on different databases.
+ *
+ * The use of the PropertyTag attribute is prohibited for custom properties.
+ * Instead, use the PropertySetId attribute and the PropertyName or
+ * PropertyId attribute.
+ *
+ * Important: Access any custom property between 0x8000 and 0xFFFE by using
+ * the GUID + name/ID.
+ *
+ * If the PropertyTag attribute is used, the DistinguishedPropertySetId,
+ * PropertySetId, PropertyName, and PropertyId attributes cannot be used.
+ *
+ * Note: You cannot use a property tag attribute for properties within the
+ * custom range 0x8000-0xFFFE. You must use a named property in this case.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PropertyTag;
+
+ /**
+ * Represents the property type of a property tag.
+ *
+ * This corresponds to the least significant word in a property tag. The
+ * PropertyType Attribute table later in this topic contains the possible
+ * values for this attribute.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MapiPropertyTypeType
+ */
+ public $PropertyType;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToIndexedFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToIndexedFieldType.php
new file mode 100644
index 00000000..c5033701
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToIndexedFieldType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PathToIndexedFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies individual members of a dictionary.
+ *
+ * @package php-ews\Type
+ */
+class PathToIndexedFieldType extends BasePathToElementType
+{
+ /**
+ * Identifies the member of the dictionary to return.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $FieldIndex;
+
+ /**
+ * FieldURI property
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DictionaryURIType
+ */
+ public $FieldURI;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToUnindexedFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToUnindexedFieldType.php
new file mode 100644
index 00000000..ceb3afc8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PathToUnindexedFieldType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PathToUnindexedFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies frequently referenced properties by URI.
+ *
+ * @package php-ews\Type
+ */
+class PathToUnindexedFieldType extends BasePathToElementType
+{
+ /**
+ * Identifies the URI of the property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\UnindexedFieldURIType
+ */
+ public $FieldURI;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PeriodType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PeriodType.php
new file mode 100644
index 00000000..b135b5b5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PeriodType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PeriodType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the name, time offset, and unique identifier for a specific stage of
+ * the time zone.
+ *
+ * @package php-ews\Type
+ */
+class PeriodType extends Type
+{
+ /**
+ * An xs:duration value that represents the time offset from Coordinated
+ * Universal Time (UTC) for the period.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Bias;
+
+ /**
+ * A string value that represents the identifier for the period.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Id;
+
+ /**
+ * A string value that represents the descriptive name of the period.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Name;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionSetType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionSetType.php
new file mode 100644
index 00000000..3b8af14d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionSetType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PermissionSetType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Contains all the permissions that are configured for a folder.
+ *
+ * @package php-ews\Type
+ */
+class PermissionSetType extends Type
+{
+ /**
+ * Contains the collection of permissions for a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPermissionsType
+ */
+ public $Permissions;
+
+ /**
+ * Contains an array of unknown entries that cannot be resolved against the
+ * Active Directory directory service.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfUnknownEntriesType
+ */
+ public $UnknownEntries;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionType.php
new file mode 100644
index 00000000..a6f947cb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PermissionType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PermissionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the access that a user has to a folder.
+ *
+ * @package php-ews\Type
+ */
+class PermissionType extends BasePermissionType
+{
+ /**
+ * Represents the combination of permissions that a user has on a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PermissionLevelType
+ */
+ public $PermissionLevel;
+
+ /**
+ * Indicates whether a user has permission to read items within a folder.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PermissionReadAccessType
+ */
+ public $ReadItems;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaAttributionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaAttributionType.php
new file mode 100644
index 00000000..6c0e0e93
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaAttributionType.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PersonaAttributionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an instance in an array of attributes for a Persona.
+ *
+ * @package php-ews\Type
+ */
+class PersonaAttributionType extends Type
+{
+ /**
+ * Defines the display name of a folder, contact, distribution list,
+ * delegate user, or rule.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Contains the identifier and change key of a folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $FolderId;
+
+ /**
+ * Specifies a string that uniquely identifies an app or an attribution in a
+ * persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Id;
+
+ /**
+ * Contains a Boolean value that indicates whether the underlying contact or
+ * Active Directory recipient should be hidden or displayed as part of the
+ * persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsHidden;
+
+ /**
+ * Specifies a Boolean value that indicates whether the underlying contact
+ * or Active Directory recipient is a quick contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsQuickContact;
+
+ /**
+ * Specifies whether the underlying contact or Active Directory recipient
+ * can be written to.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsWritable;
+
+ /**
+ * Specifies the identifier of the contact or Active Directory recipient.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $SourceId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPhoneNumberType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPhoneNumberType.php
new file mode 100644
index 00000000..44d363f5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPhoneNumberType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PersonaPhoneNumberType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a phone number and type information and is associated with a set
+ * of attributions.
+ *
+ * @package php-ews\Type
+ */
+class PersonaPhoneNumberType extends Type
+{
+ /**
+ * Specifies the phone number.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Number;
+
+ /**
+ * Specifies the type of phone number, for example, "Home" or "Business".
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Type;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPostalAddressType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPostalAddressType.php
new file mode 100644
index 00000000..39ba34de
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaPostalAddressType.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PersonaPostalAddressType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a postal address associated with a persona.
+ *
+ * @package php-ews\Type
+ */
+class PersonaPostalAddressType extends Type
+{
+ /**
+ * Specifies the accuracy of the latitude and longitude of the associated
+ * postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var float
+ */
+ public $Accuracy;
+
+ /**
+ * Specifies the altitude of a postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var float
+ */
+ public $Altitude;
+
+ /**
+ * Specifies the accuracy of the altitude property for a postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var float
+ */
+ public $AltitudeAccuracy;
+
+ /**
+ * Represents the city name that is associated with a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $City;
+
+ /**
+ * Identifies a country identifier in a postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Country;
+
+ /**
+ * Specifies the formatted display value of the associated postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $FormattedAddress;
+
+ /**
+ * Specifies the latitude of the location of the associated postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var float
+ */
+ public $Latitude;
+
+ /**
+ * Specifies information about the origin of the associated postal address,
+ * for example, a contact or a telephone book.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\LocationSourceType
+ */
+ public $LocationSource;
+
+ /**
+ * Contains a string specifying a Uniform Resource Identifier (URI) of the
+ * associated postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $LocationUri;
+
+ /**
+ * Specifies the longitude of the location of the associated postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var float
+ */
+ public $Longitude;
+
+ /**
+ * Specifies the "post office box" portion of a postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var type
+ */
+ public $PostOfficeBox;
+
+ /**
+ * Represents the postal code for a contact item.
+ *
+ * @since Exchange 2013
+ *
+ * @var type
+ */
+ public $PostalCode;
+
+ /**
+ * Represents the state of residence for a contact item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $State;
+
+ /**
+ * Represents a street address for a contact item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Street;
+
+ /**
+ * Specifies the type of postal address or phone number.
+ *
+ * For example, "Home" or "Business".
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Type;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaResponseShapeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaResponseShapeType.php
new file mode 100644
index 00000000..dd13ede5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaResponseShapeType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PersonaResponseShapeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a set of properties for a persona.
+ *
+ * @package php-ews\Type
+ */
+class PersonaResponseShapeType extends Type
+{
+ /**
+ * Identifies additional properties.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType
+ */
+ public $AdditionalProperties;
+
+ /**
+ * Identifies the set of properties to return in an item or folder response.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType
+ */
+ public $BaseShape;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaType.php
new file mode 100644
index 00000000..596c80a9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PersonaType.php
@@ -0,0 +1,972 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PersonaType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a set of persona data.
+ *
+ * @package php-ews\Type
+ */
+class PersonaType extends Type
+{
+ /**
+ * Specifies an array of assistant names and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $AssistantNames;
+
+ /**
+ * Specifies an array of assistant phone numbers and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $AssistantPhoneNumbers;
+
+ /**
+ * Specifies an array of attribution information for one or more of the
+ * contacts or Active Directory recipients aggregated into the associated
+ * persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPersonaAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Specifies an array of birthdays, stored as strings, and the identifiers
+ * of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Birthdays;
+
+ /**
+ * Specifies an array of BodyContentAttributedValue elements.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfBodyContentAttributedValuesType
+ */
+ public $Bodies;
+
+ /**
+ * Specifies an array of business addresses and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPostalAddressAttributedValuesType
+ */
+ public $BusinessAddresses;
+
+ /**
+ * Specifies an array of business home pages and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $BusinessHomePages;
+
+ /**
+ * Specifies an array of business phone numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $BusinessPhoneNumbers;
+
+ /**
+ * Specifies an array of BusinessPhoneNumber2 elements and the identifiers
+ * of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $BusinessPhoneNumbers2;
+
+ /**
+ * Specifies an array of call-back phone numbers and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $CallbackPhones;
+
+ /**
+ * Specifies an array of car phone numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $CarPhones;
+
+ /**
+ * Specifies an array of child names and identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringArrayAttributedValuesType
+ */
+ public $Children;
+
+ /**
+ * Represents the company name that is associated with a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $CompanyName;
+
+ /**
+ * Contains an array of company names and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $CompanyNames;
+
+ /**
+ * Contains the sort key for a company name.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $CompanyNameSortKey;
+
+ /**
+ * Specifies when the persona was created.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $CreationTime;
+
+ /**
+ * Represents the contact's department at work.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Department;
+
+ /**
+ * Specifies an array of department names and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Departments;
+
+ /**
+ * Contains the display name of the persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Specifies the display name of the associated persona in the format,
+ * "First Name", "Last Name".
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayNameFirstLast;
+
+ /**
+ * Specifies the header for the display name, first name first.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayNameFirstLastHeader;
+
+ /**
+ * Contains the sort key for a display name in first name, last name order.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayNameFirstLastSortKey;
+
+ /**
+ * Specifies the display name of the associated persona in the format, "Last
+ * Name", "First Name".
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayNameLastFirst;
+
+ /**
+ * Specifies the header for the display name, last name first.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayNameLastFirstHeader;
+
+ /**
+ * Contains the sort key for a display name in last name, first name order.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayNameLastFirstSortKey;
+
+ /**
+ * Specifies the prefix of the display name of the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayNamePrefix;
+
+ /**
+ * Specifies an array of display name prefixes and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $DisplayNamePrefixes;
+
+ /**
+ * Specifies an array of display names and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $DisplayNames;
+
+ /**
+ * Specifies the fully resolved SMTP address for the site mailbox or the
+ * associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $EmailAddress;
+
+ /**
+ * Specifies an array of all email addresses of the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $EmailAddresses;
+
+ /**
+ * Specifies an array of EmailAddressAttributedValue values and the
+ * identifiers of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressAttributedValuesType
+ */
+ public $Emails1;
+
+ /**
+ * Contains an array of EmailAddressAttributedValue values and the
+ * identifiers of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressAttributedValuesType
+ */
+ public $Emails2;
+
+ /**
+ * Specifies an array of EmailAddressAttributedValue values and the
+ * identifiers of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressAttributedValuesType
+ */
+ public $Emails3;
+
+ /**
+ * Contains the extended properties used for a persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfExtendedPropertyAttributedValueType
+ */
+ public $ExtendedProperties;
+
+ /**
+ * Represents how a contact or distribution list is filed in the Contacts
+ * folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $FileAs;
+
+ /**
+ * Specifies the header for the File As option.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $FileAsHeader;
+
+ /**
+ * Specifies the FileAs identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $FileAsId;
+
+ /**
+ * Specifies an array of StringAttributedValue elements and the identifiers
+ * of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $FileAsIds;
+
+ /**
+ * Specifies an array of StringAttributedValue elements and the identifiers
+ * of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $FileAses;
+
+ /**
+ * Contains a list of folder identifiers.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfFolderIdType
+ */
+ public $FolderIds;
+
+ /**
+ * Represents a generational abbreviation that follows the full name of a
+ * contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Generation;
+
+ /**
+ * Specifies an array of generation values and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Generations;
+
+ /**
+ * Contains a contact's given name.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $GivenName;
+
+ /**
+ * Specifies an array of given name values and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $GivenNames;
+
+ /**
+ * Specifies an array of hobbies and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Hobbies;
+
+ /**
+ * Specifies an array of home addresses and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPostalAddressAttributedValuesType
+ */
+ public $HomeAddresses;
+
+ /**
+ * Specifies the city of the home address of the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $HomeCity;
+
+ /**
+ * Contains the sort key for the home city.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $HomeCitySortKey;
+
+ /**
+ * Specifies an array of home fax numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $HomeFaxes;
+
+ /**
+ * Specifies an array of home phone numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $HomePhones;
+
+ /**
+ * Specifies an array of HomePhone2 values and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $HomePhones2;
+
+ /**
+ * Contains the primary instant messaging address of a persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ImAddress;
+
+ /**
+ * Specifies an array of instant message addresses and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $ImAddresses;
+
+ /**
+ * Specifies an array of instant message addresses and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $ImAddresses2;
+
+ /**
+ * Specifies an array of instant message addresses and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $ImAddresses3;
+
+ /**
+ * Specifies an array of initials values and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Initials;
+
+ /**
+ * Represents the location of a meeting, appointment, or persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Location;
+
+ /**
+ * Specifies an array of location values and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Locations;
+
+ /**
+ * Specifies an array of manager names and the identifiers of their source
+ * attributions for a persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Managers;
+
+ /**
+ * Represents the middle name of a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $MiddleName;
+
+ /**
+ * Specifies an array of middle name values and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $MiddleNames;
+
+ /**
+ * Specifies an array of mobile phone numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $MobilePhones;
+
+ /**
+ * Specifies an array of MobilePhone values and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $MobilePhones2;
+
+ /**
+ * Represents the nickname of a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Nickname;
+
+ /**
+ * Specifies an array of nickname values and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Nicknames;
+
+ /**
+ * Specifies an array of office locations and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $OfficeLocations;
+
+ /**
+ * Specifies an array of organizational main phone numbers and the
+ * identifiers of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $OrganizationMainPhones;
+
+ /**
+ * Specifies an array of address values and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPostalAddressAttributedValuesType
+ */
+ public $OtherAddresses;
+
+ /**
+ * Specifies an array of fax phone number values and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $OtherFaxes;
+
+ /**
+ * Specifies an array of phone values and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $OtherPhones2;
+
+ /**
+ * Specifies an array of telephone values and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $OtherTelephones;
+
+ /**
+ * Specifies an array of pager phone numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $Pagers;
+
+ /**
+ * Specifies the persona identifier for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $PersonaId;
+
+ /**
+ * Specifies whether the information in the associated persona is complete
+ * or partial.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $PersonaObjectStatus;
+
+ /**
+ * Specifies the type of the persona.
+ *
+ * For example, a person or a distribution list.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $PersonaType;
+
+ /**
+ * Specifies an array of home pages and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $PersonalHomePages;
+
+ /**
+ * Specifies the default phone number of the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaPhoneNumberType
+ */
+ public $PhoneNumber;
+
+ /**
+ * Specifies an array of Profession values and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Professions;
+
+ /**
+ * Specifies an array of radio phone numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $RadioPhones;
+
+ /**
+ * Specifies an integer that represents how relevant the associated persona
+ * is to the client.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $RelevanceScore;
+
+ /**
+ * Specifies an array of school names and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Schools;
+
+ /**
+ * Specifies an array of spouse or partner names and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $SpouseNames;
+
+ /**
+ * Represents the surname of a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Surname;
+
+ /**
+ * Specifies an array of surname values and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Surnames;
+
+ /**
+ * Specifies an array of Telex numbers and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $TelexNumbers;
+
+ /**
+ * Represents the title of a contact.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Title;
+
+ /**
+ * Specifies an array of job titles and the identifiers of their source
+ * attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $Titles;
+
+ /**
+ * Specifies an array of TTY or TDD text telephone numbers and the
+ * identifiers of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $TTYTDDPhoneNumbers;
+
+ /**
+ * Specifies an array of wedding anniversary dates, stored as strings, and
+ * the identifiers of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $WeddingAnniversaries;
+
+ /**
+ * Specifies the city where the associated persona works.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $WorkCity;
+
+ /**
+ * Contains the sort key for the work city values associated with a persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $WorkCitySortKey;
+
+ /**
+ * Specifies an array of work fax numbers and the identifiers of their
+ * source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfPhoneNumberAttributedValuesType
+ */
+ public $WorkFaxes;
+
+ /**
+ * Specifies the phonetic Japanese company name of the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $YomiCompanyName;
+
+ /**
+ * Specifies an array of phonetic Japanese company names and the identifiers
+ * of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $YomiCompanyNames;
+
+ /**
+ * Represents the name that is used in Japan for the searchable or phonetic
+ * spelling for a Japanese first name.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $YomiFirstName;
+
+ /**
+ * Specifies an array of phonetic Japanese first names and the identifiers
+ * of their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $YomiFirstNames;
+
+ /**
+ * Represents the name that is used in Japan for the searchable or phonetic
+ * spelling for a Japanese last name.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $YomiLastName;
+
+ /**
+ * Specifies an array of phonetic Japanese last names and the identifiers of
+ * their source attributions for the associated persona.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringAttributedValuesType
+ */
+ public $YomiLastNames;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallIdType.php
new file mode 100644
index 00000000..a7daff00
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallIdType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PhoneCallIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the identifier of a phone call.
+ *
+ * @package php-ews\Type
+ */
+class PhoneCallIdType extends Type
+{
+ /**
+ * Identifies the phone call to disconnect.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Id;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallInformationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallInformationType.php
new file mode 100644
index 00000000..0a35c327
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneCallInformationType.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PhoneCallInformationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the state information for a phone call.
+ *
+ * @package php-ews\Type
+ */
+class PhoneCallInformationType extends Type
+{
+ /**
+ * Specifies the cause of a connection failure.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ConnectionFailureCauseType
+ */
+ public $ConnectionFailureCause;
+
+ /**
+ * Specifies the state for a phone call.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PhoneCallStateType
+ */
+ public $PhoneCallState;
+
+ /**
+ * Specifies the SIP response code.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $SIPResponseCode;
+
+ /**
+ * Specifies the SIP response text.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $SIPResponseText;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberAttributedValueType.php
new file mode 100644
index 00000000..da006a43
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberAttributedValueType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PhoneNumberAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a phone number and its associated attributions.
+ *
+ * @package php-ews\Type
+ */
+class PhoneNumberAttributedValueType extends Type
+{
+ /**
+ * Specifies an array of attributions for the Value element.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfValueAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Specifies a phone number and type information.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaPhoneNumberType
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryEntryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryEntryType.php
new file mode 100644
index 00000000..c558c04e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryEntryType.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PhoneNumberDictionaryEntryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a telephone number for a contact.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a common EntryType class.
+ * @todo Create a common TextEntryType class.
+ */
+class PhoneNumberDictionaryEntryType extends Type
+{
+ /**
+ * Value that represents the telephone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $_;
+
+ /**
+ * Identifies the telephone number.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PhoneNumberKeyType
+ */
+ public $Key;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryType.php
new file mode 100644
index 00000000..98333160
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhoneNumberDictionaryType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PhoneNumberDictionaryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a collection of telephone numbers for a contact.
+ *
+ * @package php-ews\Type
+ */
+class PhoneNumberDictionaryType extends Type
+{
+ /**
+ * Represents a telephone number for a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhoneNumberDictionaryEntryType
+ */
+ public $Entry;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryEntryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryEntryType.php
new file mode 100644
index 00000000..a24adf44
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryEntryType.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PhysicalAddressDictionaryEntryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes a single physical address for a contact item.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a common EntryType class.
+ * @todo Create a common TextEntryType class.
+ */
+class PhysicalAddressDictionaryEntryType extends Type
+{
+ /**
+ * Represents the city name that is associated with a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $City;
+
+ /**
+ * Represents the country or region for a given physical address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $CountryOrRegion;
+
+ /**
+ * Identifies a physical address.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PhysicalAddressKeyType
+ */
+ public $Key;
+
+ /**
+ * Represents the postal code for a contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $PostalCode;
+
+ /**
+ * Represents the state of residence for a contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $State;
+
+ /**
+ * Represents a street address for a contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Street;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryType.php
new file mode 100644
index 00000000..2338685e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PhysicalAddressDictionaryType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PhysicalAddressDictionaryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a collection of physical addresses that are associated with a
+ * contact.
+ *
+ * @package php-ews\Type
+ */
+class PhysicalAddressDictionaryType extends Type
+{
+ /**
+ * Describes a single physical address for a contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PhysicalAddressDictionaryEntryType
+ */
+ public $Entry;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostItemType.php
new file mode 100644
index 00000000..b4766098
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostItemType.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PostItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a post item in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class PostItemType extends ItemType
+{
+ /**
+ * Contains a binary ID that represents the thread to which this message
+ * belongs.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $ConversationIndex;
+
+ /**
+ * Represents the conversation identifier.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ConversationTopic;
+
+ /**
+ * Represents the address from which the post item was sent.
+ *
+ * The From element can only be set at creation time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $From;
+
+ /**
+ * Represents the Internet message identifier of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $InternetMessageId;
+
+ /**
+ * Indicates whether a message has been read.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsRead;
+
+ /**
+ * Represents the time that a PostItem was posted.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $PostedTime;
+
+ /**
+ * Represents the Usenet header that is used to associate replies with the
+ * original messages.
+ *
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $References;
+
+ /**
+ * Identifies the sender of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $Sender;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemBaseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemBaseType.php
new file mode 100644
index 00000000..98c49a06
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemBaseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PostReplyItemBaseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for posting item replies.
+ *
+ * @package php-ews\Type
+ */
+class PostReplyItemBaseType extends ResponseObjectType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemType.php
new file mode 100644
index 00000000..40a9af4e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostReplyItemType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PostReplyItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a reply to a post item.
+ *
+ * @package php-ews\Type
+ */
+class PostReplyItemType extends PostReplyItemBaseType
+{
+ /**
+ * Represents the new body content of a post item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BodyType
+ */
+ public $NewBodyContent;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostalAddressAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostalAddressAttributedValueType.php
new file mode 100644
index 00000000..1454a0ac
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PostalAddressAttributedValueType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PostalAddressAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an instance of an array of postal addresses and their associated
+ * attributions.
+ *
+ * @package php-ews\Type
+ */
+class PostalAddressAttributedValueType extends Type
+{
+ /**
+ * Specifies an array of attributions for its associated Value element.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfValueAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Specifies information associated with a postal address.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PersonaPostalAddressType
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemMailboxType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemMailboxType.php
new file mode 100644
index 00000000..46969626
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemMailboxType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PreviewItemMailboxType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the mailbox identifier and the user’s primary Simple Mail Transfer
+ * Protocol (SMTP) address.
+ *
+ * @package php-ews\Type
+ */
+class PreviewItemMailboxType extends Type
+{
+ /**
+ * Specifies an identifier for the mailbox that is accessed by discovery
+ * search.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $MailboxId;
+
+ /**
+ * Specifies the primary Simple Mail Transfer Protocol (SMTP) address of the
+ * mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $PrimarySmtpAddress;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemResponseShapeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemResponseShapeType.php
new file mode 100644
index 00000000..44a4844a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PreviewItemResponseShapeType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PreviewItemResponseShapeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the requested property set to be returned in a discovery search.
+ *
+ * @package php-ews\Type
+ */
+class PreviewItemResponseShapeType extends Type
+{
+ /**
+ * Identifies additional properties.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPathsToElementType
+ */
+ public $AdditionalProperties;
+
+ /**
+ * Specifies either the default preview with all properties returned or a
+ * compact preview with fewer properties returned.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\PreviewItemBaseShapeType
+ */
+ public $BaseShape;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PrivateCatalogAddInsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PrivateCatalogAddInsType.php
new file mode 100644
index 00000000..c09e7c31
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PrivateCatalogAddInsType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PrivateCatalogAddInsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Undocumented.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Update once documentation exists.
+ */
+class PrivateCatalogAddInsType extends Type
+{
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $ProductId;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\AddInStateType
+ *
+ * @todo Update once documentation exists.
+ */
+ public $State;
+
+ /**
+ * Undocumented.
+ *
+ * @since Exchange 2016
+ *
+ * @var string
+ *
+ * @todo Update once documentation exists.
+ */
+ public $Version;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProposeNewTimeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProposeNewTimeType.php
new file mode 100644
index 00000000..75c747bf
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProposeNewTimeType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProposeNewTimeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a response object that indicates that a meeting attendee can
+ * propose a new meeting time.
+ *
+ * @package php-ews\Type
+ */
+class ProposeNewTimeType extends ResponseObjectType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleActionType.php
new file mode 100644
index 00000000..9cc8d3bc
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleActionType.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRuleActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies what action must be executed if the condition part of a rule
+ * passes.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRuleActionType extends Type
+{
+ /**
+ * Specifies arguments to the action.
+ *
+ * This property should be left empty if the specified action does not
+ * require arguments to be specified. This property can include one or more
+ * values if an action requires one or more arguments. The
+ * RightsProtectMessage action will contain a single argument.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleArgumentType
+ */
+ public $Argument;
+
+ /**
+ * Identifies the name of the action.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Name;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleAndType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleAndType.php
new file mode 100644
index 00000000..708eeb62
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleAndType.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRuleAndType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies that all child elements must match to evaluate to true.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRuleAndType extends Type
+{
+ /**
+ * Evaluates to true if all recipients of an e-mail message are internal to
+ * the sender's organization.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $AllInternal;
+
+ /**
+ * Specifies that all child elements must match to evaluate to true.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleAndType
+ */
+ public $And;
+
+ /**
+ * Specifies that any recipient of the e-mail message matches any of the
+ * specified recipients in the child Value (ProtectionRuleValueType)
+ * elements.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleRecipientIsType
+ */
+ public $RecipientIs;
+
+ /**
+ * Specifies that the department of the sender matches any of the specified
+ * departments in the child Value (ProtectionRuleValueType) elements.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleSenderDepartmentsType
+ */
+ public $SenderDepartments;
+
+ /**
+ * Specifies a condition that always matches.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $True;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleArgumentType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleArgumentType.php
new file mode 100644
index 00000000..3c7d81ea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleArgumentType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRuleArgumentType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies an argument to be passed to an action.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRuleArgumentType extends Type
+{
+ /**
+ * A non-empty string value that represents the value of an argument to the
+ * action part of a protection rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleConditionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleConditionType.php
new file mode 100644
index 00000000..d7cfdf65
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleConditionType.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRuleConditionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a condition that must be satisfied for the action part of a rule
+ * to be executed.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRuleConditionType extends Type
+{
+ /**
+ * Evaluates to true if all recipients of an e-mail message are internal to
+ * the sender's organization.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $AllInternal;
+
+ /**
+ * Specifies that all child elements must match to evaluate to true.
+ *
+ * Specifies that there must be more than one protection rule child
+ * condition.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleAndType
+ */
+ public $And;
+
+ /**
+ * Specifies that any recipient of the e-mail message matches any of the
+ * specified recipients in the child Value (ProtectionRuleValueType)
+ * elements.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleRecipientIsType
+ */
+ public $RecipientIs;
+
+ /**
+ * Specifies that the department of the sender matches any of the specified
+ * departments in the child Value (ProtectionRuleValueType) elements.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleSenderDepartmentsType
+ */
+ public $SenderDepartments;
+
+ /**
+ * Specifies a condition that always matches.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $True;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleRecipientIsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleRecipientIsType.php
new file mode 100644
index 00000000..5a0ccf4b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleRecipientIsType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRuleRecipientIsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies that any recipient of the e-mail message matches any of the
+ * specified recipients in the child Value (ProtectionRuleValueType) elements.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRuleRecipientIsType extends Type
+{
+ /**
+ * Identifies a recipient.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleSenderDepartmentsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleSenderDepartmentsType.php
new file mode 100644
index 00000000..6f4fbf79
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleSenderDepartmentsType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRuleSenderDepartmentsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies that the department of the sender matches any of the specified
+ * departments in the child Value (ProtectionRuleValueType) elements.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRuleSenderDepartmentsType extends Type
+{
+ /**
+ * Identifies a single sender department.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleType.php
new file mode 100644
index 00000000..969a0d5a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRuleType.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRuleType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single protection rule.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRuleType extends Type
+{
+ /**
+ * Identifies what action must be executed if the condition part of the rule
+ * matches.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleActionType
+ */
+ public $Action;
+
+ /**
+ * Identifies the condition that must be satisfied for the action part of
+ * the rule to be executed.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ProtectionRuleConditionType
+ */
+ public $Condition;
+
+ /**
+ * Identifies the name of the rule.
+ *
+ * This property is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Specifies the rule priority.
+ *
+ * This property is required with a minimum value of 1.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $Priority;
+
+ /**
+ * Specifies whether the rule is mandatory.
+ *
+ * If the rule is mandatory, this attribute value must be false
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $UserOverridable;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRulesServiceConfiguration.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRulesServiceConfiguration.php
new file mode 100644
index 00000000..b696b579
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ProtectionRulesServiceConfiguration.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ProtectionRulesServiceConfiguration.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents service configuration information for the protection rules
+ * service.
+ *
+ * @package php-ews\Type
+ */
+class ProtectionRulesServiceConfiguration extends ServiceConfiguration
+{
+ /**
+ * Identifies the list of internal SMTP domains of the organization.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\SmtpDomainList
+ */
+ public $InternalDomains;
+
+ /**
+ * Specifies how often, in whole hours, the client should request protection
+ * rules from the server.
+ *
+ * This attribute is required and its value must be an integer that is equal
+ * to or greater than 1.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $RefreshInterval;
+
+ /**
+ * An array of protection rules.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfProtectionRulesType
+ */
+ public $Rules;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PullSubscriptionRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PullSubscriptionRequestType.php
new file mode 100644
index 00000000..73bd4d51
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PullSubscriptionRequestType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PullSubscriptionRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a subscription to a pull-based event notification subscription.
+ *
+ * @package php-ews\Type
+ */
+class PullSubscriptionRequestType extends BaseSubscriptionRequestType
+{
+ /**
+ * Represents the duration, in minutes, that the subscription can remain
+ * idle without a GetEvents request from the client.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ *
+ * @todo Determine if we need SubscriptionTimeoutType.
+ */
+ public $Timeout;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PushSubscriptionRequestType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PushSubscriptionRequestType.php
new file mode 100644
index 00000000..4fb7ee2a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/PushSubscriptionRequestType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\PushSubscriptionRequestType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a subscription to a push-based event notification subscription.
+ *
+ * @package php-ews\Type
+ */
+class PushSubscriptionRequestType extends BaseSubscriptionRequestType
+{
+ /**
+ * Represents the frequency, specified in minutes, at which notification
+ * messages will be sent to the client when no events have occurred.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ *
+ * @todo Determine if we need SubscriptionStatusFrequencyType.
+ */
+ public $StatusFrequency;
+
+ /**
+ * Represents the location of the client Web service for push notifications.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $URL;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/QueryStringType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/QueryStringType.php
new file mode 100644
index 00000000..d37ed672
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/QueryStringType.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\QueryStringType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a mailbox query string based on Advanced Query Syntax (AQS).
+ *
+ * @package php-ews\Type
+ *
+ * @todo Create a base string class?
+ */
+class QueryStringType extends Type
+{
+ /**
+ * Text value of the query string.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @link http://msdn.microsoft.com/en-us/library/ee693615(v=exchg.150).aspx
+ */
+ public $_;
+
+ /**
+ * Indicates that the cache should be reset.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $ResetCache;
+
+ /**
+ * Indicates that deleted items should be returned.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $ReturnDeletedItems;
+
+ /**
+ * Indicates that highlighted terms should be returned.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $ReturnHighlightTerms;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecipientTrackingEventType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecipientTrackingEventType.php
new file mode 100644
index 00000000..18df04ca
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecipientTrackingEventType.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecipientTrackingEventType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents information for a single event for a recipient.
+ *
+ * @package php-ews\Type
+ */
+class RecipientTrackingEventType extends Type
+{
+ /**
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $BccRecipient;
+
+ /**
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Date;
+
+ /**
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MessageTrackingDeliveryStatusType
+ */
+ public $DeliveryStatus;
+
+ /**
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $EventData;
+
+ /**
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MessageTrackingEventDescriptionType
+ */
+ public $EventDescription;
+
+ /**
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $HiddenRecipient;
+
+ /**
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $InternalId;
+
+ /**
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTrackingPropertiesType
+ */
+ public $Properties;
+
+ /**
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Recipient;
+
+ /**
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $RootAddress;
+
+ /**
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Server;
+
+ /**
+ * This element is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $UniquePathId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrencePatternBaseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrencePatternBaseType.php
new file mode 100644
index 00000000..a76a404c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrencePatternBaseType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurrencePatternBaseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for recurrence patterns.
+ *
+ * @package php-ews\Type
+ */
+abstract class RecurrencePatternBaseType extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceRangeBaseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceRangeBaseType.php
new file mode 100644
index 00000000..d1418fbe
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceRangeBaseType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurrenceRangeBaseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for recurrence ranges,
+ *
+ * @package php-ews\Type
+ */
+abstract class RecurrenceRangeBaseType extends Type
+{
+ /**
+ * Represents the start date of a recurring task or calendar item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a date object that extends DateTime.
+ */
+ public $StartDate;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceType.php
new file mode 100644
index 00000000..e50975e3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurrenceType.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurrenceType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the recurrence pattern for calendar items and meeting requests.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Implement RecurrencePatternTypes trait.
+ * @todo Implement RecurrenceRangeTypes trait.
+ */
+class RecurrenceType extends Type
+{
+ /**
+ * Represents a monthly recurrence pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AbsoluteMonthlyRecurrencePatternType
+ */
+ public $AbsoluteMonthlyRecurrence;
+
+ /**
+ * Represents a yearly recurrence pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\AbsoluteYearlyRecurrencePatternType
+ */
+ public $AbsoluteYearlyRecurrence;
+
+ /**
+ * Describes the frequency, in days, in which a calendar item or task
+ * recurs.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DailyRecurrencePatternType
+ */
+ public $DailyRecurrence;
+
+ /**
+ * Describes the start date and the end date of an item recurrence pattern.
+ *
+ * The use of this element excludes the use of the NoEndRecurrence and
+ * NumberedRecurrence elements.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EndDateRecurrenceRangeType
+ */
+ public $EndDateRecurrence;
+
+ /**
+ * Describes a recurrence pattern that does not have a defined end date.
+ *
+ * The use of this element excludes the use of the EndDateRecurrence and
+ * NumberedRecurrence elements.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\NoEndRecurrenceRangeType
+ */
+ public $NoEndRecurrence;
+
+ /**
+ * Describes the start date and the number of occurrences of a recurring
+ * item.
+ *
+ * The use of this element excludes the use of the NoEndRecurrence and
+ * EndDateRecurrence elements.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\NumberedRecurrenceRangeType
+ */
+ public $NumberedRecurrence;
+
+ /**
+ * Describes a relative monthly recurrence pattern for a recurring calendar
+ * item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RelativeMonthlyRecurrencePatternType
+ */
+ public $RelativeMonthlyRecurrence;
+
+ /**
+ * Describes a relative yearly recurrence pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RelativeYearlyRecurrencePatternType
+ */
+ public $RelativeYearlyRecurrence;
+
+ /**
+ * Describes the frequency, in weeks, and the days that a calendar item or
+ * task recurs.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\WeeklyRecurrencePatternType
+ */
+ public $WeeklyRecurrence;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDateTransitionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDateTransitionType.php
new file mode 100644
index 00000000..65ca16eb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDateTransitionType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurringDateTransitionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a time zone transition that occurs on a specific date each year.
+ *
+ * @package php-ews\Type
+ */
+class RecurringDateTransitionType extends RecurringTimeTransitionType
+{
+ /**
+ * The day of the month on which the time zone transition occurs.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $Day;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDayTransitionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDayTransitionType.php
new file mode 100644
index 00000000..589176e2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringDayTransitionType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurringDayTransitionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a time zone transition that occurs on the same day each year.
+ *
+ * @package php-ews\Type
+ */
+class RecurringDayTransitionType extends RecurringTimeTransitionType
+{
+ /**
+ * The day of the week on which the time zone transition occurs.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DayOfWeekType
+ */
+ public $DayOfWeek;
+
+ /**
+ * The occurrence of the day of the week in the month that the time zone
+ * transition occurs.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\Occurrence
+ */
+ public $Occurrence;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdRanges.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdRanges.php
new file mode 100644
index 00000000..cbd261c8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdRanges.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurringMasterItemIdRanges.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an occurrence range.
+ *
+ * @package php-ews\Type
+ */
+class RecurringMasterItemIdRanges extends ItemIdType
+{
+ /**
+ * Specifies an array of recurrence ranges.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfOccurrenceRangesType
+ */
+ public $Ranges;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdType.php
new file mode 100644
index 00000000..9ff28aac
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringMasterItemIdType.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurringMasterItemIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a recurrence master item by identifying the identifiers of one of
+ * its related occurrence items.
+ *
+ * @package php-ews\Type
+ */
+class RecurringMasterItemIdType extends BaseItemIdType
+{
+ /**
+ * Identifies a specific version of a single occurrence of a recurring
+ * master item.
+ *
+ * Additionally, the recurring master item is also identified because it and
+ * the single occurrence will contain the same change key.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ChangeKey;
+
+ /**
+ * Identifies a single occurrence of a recurring master item.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $OccurrenceId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringTimeTransitionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringTimeTransitionType.php
new file mode 100644
index 00000000..88aaacd9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RecurringTimeTransitionType.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RecurringTimeTransitionType;
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for recurring time transitions.
+ *
+ * @package php-ews\Type
+ */
+abstract class RecurringTimeTransitionType extends TransitionType
+{
+ /**
+ * The month in which the time transition occurs.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $Month;
+
+ /**
+ * The duration offset from Coordinated Universal Time (UTC) for the time
+ * transition.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $TimeOffset;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReferenceItemResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReferenceItemResponseType.php
new file mode 100644
index 00000000..f2f8a981
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReferenceItemResponseType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ReferenceItemResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for responding to items with a reference.
+ *
+ * ObjectName property is prohibited.
+ *
+ * @package php-ews\Type
+ */
+class ReferenceItemResponseType extends ResponseObjectType
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @prohibited
+ */
+ public $ObjectName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RegeneratingPatternBaseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RegeneratingPatternBaseType.php
new file mode 100644
index 00000000..49675aec
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RegeneratingPatternBaseType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RegeneratingPatternBaseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for regenerating patterns.
+ *
+ * @package php-ews\Type
+ */
+abstract class RegeneratingPatternBaseType extends IntervalRecurrencePatternBaseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeMonthlyRecurrencePatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeMonthlyRecurrencePatternType.php
new file mode 100644
index 00000000..d119092a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeMonthlyRecurrencePatternType.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RelativeMonthlyRecurrencePatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes a relative monthly recurrence pattern.
+ *
+ * @package php-ews\Type
+ */
+class RelativeMonthlyRecurrencePatternType extends
+ IntervalRecurrencePatternBaseType
+{
+ /**
+ * Describes which week is used in a relative monthly recurrence pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DayOfWeekIndexType
+ */
+ public $DayOfWeekIndex;
+
+ /**
+ * Describes which days of the week are in the relative monthly recurrence
+ * pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DayOfWeekType
+ */
+ public $DaysOfWeek;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeYearlyRecurrencePatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeYearlyRecurrencePatternType.php
new file mode 100644
index 00000000..634ab9ec
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RelativeYearlyRecurrencePatternType.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RelativeYearlyRecurrencePatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes a relative yearly recurrence pattern.
+ *
+ * @package php-ews\Type
+ */
+class RelativeYearlyRecurrencePatternType extends RecurrencePatternBaseType
+{
+ /**
+ * Describes which week in a month is used in a relative yearly recurrence
+ * pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DayOfWeekIndexType
+ */
+ public $DayOfWeekIndex;
+
+ /**
+ * Describes the days of the week that are used in item recurrence patterns.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DayOfWeekType
+ */
+ public $DaysOfWeek;
+
+ /**
+ * Describes the month when a yearly recurring item occurs.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\MonthNamesType
+ */
+ public $Month;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderItemActionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderItemActionType.php
new file mode 100644
index 00000000..f52dd527
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderItemActionType.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ReminderItemActionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the action for a reminder item.
+ *
+ * @package php-ews\Type
+ */
+class ReminderItemActionType extends Type
+{
+ /**
+ * Specifies the action to take on the reminder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ReminderActionType
+ */
+ public $ActionType;
+
+ /**
+ * Contains the unique identifier and change key of an item in the Exchange
+ * store.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Specifies a new time for a reminder.
+ *
+ * This is used when the ActionType element is set to Snooze, in order to
+ * delay the reminder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $NewReminderTime;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderType.php
new file mode 100644
index 00000000..b8492502
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReminderType.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ReminderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a reminder for a task or a calendar item.
+ *
+ * @package php-ews\Type
+ */
+class ReminderType extends Type
+{
+ /**
+ * The end date of the item the reminder is for.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $EndDate;
+
+ /**
+ * The unique identifier of the reminder.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * The location for the item the reminder is for.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Location;
+
+ /**
+ * The unique identifier of the recurring master item for the reminder.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $RecurringMasterItemId;
+
+ /**
+ * Specified whether the reminder is for a calendar item or a task.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ReminderGroup
+ */
+ public $ReminderGroup;
+
+ /**
+ * The time for the reminder to occur.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $ReminderTime;
+
+ /**
+ * The start date of the item the reminder is for.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $StartDate;
+
+ /**
+ * The subject of the item the reminder is for.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Subject;
+
+ /**
+ * The unique identifier of the calendar item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $UID;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RemoveItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RemoveItemType.php
new file mode 100644
index 00000000..28d25295
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RemoveItemType.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RemoveItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a response object that is used to remove a meeting item when a
+ * MeetingCancellation message is received.
+ *
+ * @package php-ews\Type
+ */
+class RemoveItemType extends ResponseObjectType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyAllToItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyAllToItemType.php
new file mode 100644
index 00000000..f9183caa
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyAllToItemType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ReplyAllToItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a reply to the sender and all identified recipients of an item in
+ * the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class ReplyAllToItemType extends SmartResponseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyBody.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyBody.php
new file mode 100644
index 00000000..68ac62f4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyBody.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ReplyBody.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the out of office (OOF) response that is sent to addresses outside
+ * the recipient's domain or trusted domains.
+ *
+ * @package php-ews\Type
+ */
+class ReplyBody extends Type
+{
+ /**
+ * Specifies the language used in the ExternalReply message.
+ *
+ * The possible values for this attribute are defined by IETF RFC 3066.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $lang;
+
+ /**
+ * Contains the OOF response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Message;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyToItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyToItemType.php
new file mode 100644
index 00000000..3c05cfda
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ReplyToItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ReplyToItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a reply to the sender of an item in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class ReplyToItemType extends SmartResponseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestAttachmentIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestAttachmentIdType.php
new file mode 100644
index 00000000..90089569
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestAttachmentIdType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RequestAttachmentIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a single attachment.
+ *
+ * @package php-ews\Type
+ */
+class RequestAttachmentIdType extends BaseItemIdType
+{
+ /**
+ * Specifies the attachment identifier.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Id;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestServerVersion.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestServerVersion.php
new file mode 100644
index 00000000..d327faa5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RequestServerVersion.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RequestServerVersion.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the Microsoft Exchange Server version of a request.
+ *
+ * @package php-ews\Type
+ */
+class RequestServerVersion extends Type
+{
+ /**
+ * Identifies the Exchange Server version used in the request.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ExchangeVersionType
+ */
+ public $Version;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResolutionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResolutionType.php
new file mode 100644
index 00000000..0f295c28
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResolutionType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ResolutionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single resolved entity.
+ *
+ * @package php-ews\Type
+ */
+class ResolutionType extends Type
+{
+ /**
+ * Represents an Exchange contact item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactItemType
+ */
+ public $Contact;
+
+ /**
+ * Identifies a mail-enabled Active Directory directory service object.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectCoreType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectCoreType.php
new file mode 100644
index 00000000..5dc8fbe6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectCoreType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ResponseObjectCoreType;
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Internal abstract base type for reply objects.
+ *
+ * @package php-ews\Type
+ */
+abstract class ResponseObjectCoreType extends MessageType
+{
+ /**
+ * The name of this reply object class as an English string.
+ *
+ * The client application is required to translate it if it's running in a
+ * different locale.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ObjectName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectType.php
new file mode 100644
index 00000000..c9e46f0c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ResponseObjectType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ResponseObjectType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base type for reply objects.
+ *
+ * @package php-ews\Type
+ */
+abstract class ResponseObjectType extends ResponseObjectCoreType
+{
+ /**
+ * Item identifier that is related to a response object.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $ReferenceItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RestrictionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RestrictionType.php
new file mode 100644
index 00000000..5cbb70cd
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RestrictionType.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RestrictionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the restriction or query that is used to filter items or folders
+ * in FindItem/FindFolder and search folder operations.
+ *
+ * @package php-ews\Type
+ */
+class RestrictionType extends MultipleOperandBooleanExpressionType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RetentionPolicyTagType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RetentionPolicyTagType.php
new file mode 100644
index 00000000..c6a4dbeb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RetentionPolicyTagType.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RetentionPolicyTagType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the retention policy for a mailbox item.
+ *
+ * @package php-ews\Type
+ */
+class RetentionPolicyTagType extends Type
+{
+ /**
+ * Specifies the descriptive text for the retention policy.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Description;
+
+ /**
+ * Defines the display name of the retention policy tag.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Indicates whether the mailbox is an archive mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsArchive;
+
+ /**
+ * Indicates whether the retention policy is visible to users.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsVisible;
+
+ /**
+ * Indicates whether the user opted in to the retention policy.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $OptedInto;
+
+ /**
+ * Specifies the action performed on items with the retention tag.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\RetentionActionType
+ */
+ public $RetentionAction;
+
+ /**
+ * Specifies the retention tag identifier.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $RetentionId;
+
+ /**
+ * Specifies the number of days that the retention policy is in effect.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $RetentionPeriod;
+
+ /**
+ * Specifies the type of folder used in a retention policy.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ElcFolderType
+ */
+ public $Type;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RoomType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RoomType.php
new file mode 100644
index 00000000..efc5985e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RoomType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RoomType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a meeting room.
+ *
+ * @package php-ews\Type
+ */
+class RoomType extends DirectoryEntryType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RootItemIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RootItemIdType.php
new file mode 100644
index 00000000..4ecb27d3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RootItemIdType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RootItemIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies the root item of a deleted item.
+ *
+ * @package php-ews\Type
+ */
+class RootItemIdType extends BaseItemIdType
+{
+ /**
+ * Identifies the new change key of the root item of a deleted item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $RootItemChangeKey;
+
+ /**
+ * Identifies the root item of a deleted item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $RootItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleActionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleActionsType.php
new file mode 100644
index 00000000..f3a0f218
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleActionsType.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RuleActionsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the set of actions that are available to be taken on a message
+ * when conditions are fulfilled.
+ *
+ * @package php-ews\Type
+ */
+class RuleActionsType extends Type
+{
+ /**
+ * Represents the categories that are stamped on e-mail messages.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $AssignCategories;
+
+ /**
+ * Identifies the ID of the folder that e-mail items will be copied to.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $CopyToFolder;
+
+ /**
+ * Indicates whether messages are to be moved to the Deleted Items folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $Delete;
+
+ /**
+ * Indicates the e-mail addresses to which messages are to be forwarded as
+ * attachments.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $ForwardAsAttachmentToRecipients;
+
+ /**
+ * Indicates the e-mail addresses to which messages are to be forwarded.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $ForwardToRecipients;
+
+ /**
+ * Specifies the importance that is to be stamped on messages.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ImportanceChoicesType
+ */
+ public $MarkImportance;
+
+ /**
+ * Indicates whether messages are to be marked as read.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $MarkAsRead;
+
+ /**
+ * Identifies the ID of the folder that e-mail items will be moved to.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TargetFolderIdType
+ */
+ public $MoveToFolder;
+
+ /**
+ * Indicates whether messages are to be permanently deleted and not saved to
+ * the Deleted Items folder.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $PermanentDelete;
+
+ /**
+ * Indicates the e-mail addresses to which messages are to be redirected.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $RedirectToRecipients;
+
+ /**
+ * Indicates the mobile phone numbers to which a Short Message Service (SMS)
+ * alert is to be sent.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $SendSMSAlertToRecipients;
+
+ /**
+ * Indicates the ID of the template message that is to be sent as a reply to
+ * incoming messages.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ServerReplyWithMessage;
+
+ /**
+ * Indicates whether subsequent rules are to be evaluated.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $StopProcessingRules;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationErrorType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationErrorType.php
new file mode 100644
index 00000000..9e86642a
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationErrorType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RuleOperationErrorType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a rule operation error.
+ *
+ * @package php-ews\Type
+ */
+class RuleOperationErrorType extends Type
+{
+ /**
+ * Indicates the index of the operation in the request that caused the rule
+ * operation error.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $OperationIndex;
+
+ /**
+ * Represents an array of rule validation errors on each rule field that has
+ * an error.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRuleValidationErrorsType
+ */
+ public $ValidationErrors;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationType.php
new file mode 100644
index 00000000..c4f70a72
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleOperationType.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RuleOperationType;
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+abstract class RuleOperationType extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateDateRangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateDateRangeType.php
new file mode 100644
index 00000000..c4205b3c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateDateRangeType.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RulePredicateDateRangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies the date range within which incoming messages have to have been
+ * received in order for the condition or exception to apply.
+ *
+ * @package php-ews\Type
+ */
+class RulePredicateDateRangeType extends Type
+{
+ /**
+ * Specifies the rule time period and indicates that the rule condition is
+ * met before this value.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $EndDateTime;
+
+ /**
+ * Specifies the rule time period and indicates that the rule condition is
+ * met after this value.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $StartDateTime;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateSizeRangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateSizeRangeType.php
new file mode 100644
index 00000000..f792c0e0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicateSizeRangeType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RulePredicateSizeRangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies the minimum and maximum sizes that incoming messages must be in
+ * order for the condition or exception to apply.
+ *
+ * @package php-ews\Type
+ */
+class RulePredicateSizeRangeType extends Type
+{
+ /**
+ * Specifies the maximum size that a message must be in order for the
+ * condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $MaximumSize;
+
+ /**
+ * Specifies the minimum size that a message must be in order for the
+ * condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $MinimumSize;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicatesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicatesType.php
new file mode 100644
index 00000000..cbb34bc3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RulePredicatesType.php
@@ -0,0 +1,369 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RulePredicatesType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies the conditions that, when fulfilled, will trigger the rule actions
+ * for a rule.
+ *
+ * @package php-ews\Type
+ */
+class RulePredicatesType extends Type
+{
+ /**
+ * Contains the categories that must be applied to an incoming message in
+ * order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Categories;
+
+ /**
+ * Indicates the strings that must appear in the body of incoming messages
+ * in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $ContainsBodyStrings;
+
+ /**
+ * Indicates the strings that must appear in the headers of incoming
+ * messages in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $ContainsHeaderStrings;
+
+ /**
+ * Indicates the strings that must appear in either the ToRecipients or
+ * CcRecipients properties of incoming messages in order for the condition
+ * or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $ContainsRecipientStrings;
+
+ /**
+ * Indicates the strings that must appear in the From property of incoming
+ * messages in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $ContainsSenderStrings;
+
+ /**
+ * Indicates the strings that must appear in either the body or the subject
+ * of incoming messages in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $ContainsSubjectOrBodyStrings;
+
+ /**
+ * Indicates the strings that must appear in the subject of incoming
+ * messages in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $ContainsSubjectStrings;
+
+ /**
+ * Specifies the flag for action value that must appear on incoming messages
+ * in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\FlaggedForActionType
+ */
+ public $FlaggedForAction;
+
+ /**
+ * Indicates the e-mail addresses from which incoming messages must be sent
+ * in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $FromAddresses;
+
+ /**
+ * Represents the e-mail account names from which incoming messages have to
+ * have been aggregated in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $FromConnectedAccounts;
+
+ /**
+ * Indicates whether incoming messages have to have attachments in order for
+ * the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $HasAttachments;
+
+ /**
+ * Specifies the importance that is stamped on incoming messages in order
+ * for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ImportanceChoicesType
+ */
+ public $Importance;
+
+ /**
+ * Indicates whether incoming messages must be approval requests in order
+ * for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsApprovalRequest;
+
+ /**
+ * Indicates whether incoming messages must be automatic forwards in order
+ * for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsAutomaticForward;
+
+ /**
+ * Indicates whether incoming messages must be automatic replies in order
+ * for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsAutomaticReply;
+
+ /**
+ * Indicates whether incoming messages must be S/MIME encrypted in order for
+ * the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsEncrypted;
+
+ /**
+ * Indicates whether incoming messages must be meeting requests in order for
+ * the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsMeetingRequest;
+
+ /**
+ * Indicates whether incoming messages must be meeting responses in order
+ * for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsMeetingResponse;
+
+ /**
+ * Indicates whether incoming messages must be non-delivery reports (NDRs)
+ * in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsNDR;
+
+ /**
+ * Indicates whether incoming messages must be permission controlled (RMS
+ * protected) in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsPermissionControlled;
+
+ /**
+ * Indicates whether incoming messages must be read receipts in order for
+ * the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsReadReceipt;
+
+ /**
+ * Indicates whether incoming messages must be S/MIME signed in order for\
+ * the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsSigned;
+
+ /**
+ * Indicates whether incoming messages must be voice mail messages in order
+ * for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsVoicemail;
+
+ /**
+ * Represents the item classes that must be stamped on incoming messages in
+ * order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $ItemClasses;
+
+ /**
+ * Represents the message classifications that must be stamped on incoming
+ * messages in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $MessageClassifications;
+
+ /**
+ * Indicates whether the owner of the mailbox must not be in the
+ * ToRecipients property of the incoming messages in order for the condition
+ * or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $NotSentToMe;
+
+ /**
+ * Indicates the sensitivity that must be stamped on incoming messages in
+ * order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SensitivityChoicesType
+ */
+ public $Sensitivity;
+
+ /**
+ * Indicates whether the owner of the mailbox has to be in the CcRecipients
+ * property of incoming messages in order for the condition or exception to
+ * apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $SentCcMe;
+
+ /**
+ * Indicates whether the owner of the mailbox has to be the only one in the
+ * ToRecipients property of incoming messages in order for the condition or
+ * exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $SentOnlyToMe;
+
+ /**
+ * Indicates the e-mail addresses that incoming messages have to have been
+ * sent to in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfEmailAddressesType
+ */
+ public $SentToAddresses;
+
+ /**
+ * Indicates whether the owner of the mailbox has to be in the ToRecipients
+ * property of incoming messages in order for the condition or exception to
+ * apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $SentToMe;
+
+ /**
+ * Indicates whether the owner of the mailbox has to be in either a
+ * ToRecipients or CcRecipients property of incoming messages in order for
+ * the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $SentToOrCcMe;
+
+ /**
+ * Specifies the date range within which incoming messages have to have been
+ * received in order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RulePredicateDateRangeType
+ */
+ public $WithinDateRange;
+
+ /**
+ * Specifies the minimum and maximum sizes that incoming messages must be in
+ * order for the condition or exception to apply.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RulePredicateSizeRangeType
+ */
+ public $WithinSizeRange;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleType.php
new file mode 100644
index 00000000..70593425
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleType.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RuleType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single rule in a user's mailbox.
+ *
+ * @package php-ews\Type
+ */
+class RuleType extends Type
+{
+ /**
+ * Represents the actions to be taken on a message when the conditions are
+ * fulfilled.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RuleActionsType
+ */
+ public $Actions;
+
+ /**
+ * Identifies the conditions that, when fulfilled, will trigger the rule
+ * actions for a rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RulePredicatesType
+ */
+ public $Conditions;
+
+ /**
+ * Contains the display name of a rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Identifies the exceptions that represent all the available rule exception
+ * conditions for the inbox rule.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RulePredicatesType
+ */
+ public $Exceptions;
+
+ /**
+ * Indicates whether the rule is enabled.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsEnabled;
+
+ /**
+ * Indicates whether the rule is in an error condition.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsInError;
+
+ /**
+ * Indicates whether the rule cannot be modified with the managed code APIs.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IsNotSupported;
+
+ /**
+ * Indicates the order in which a rule is to be run.
+ *
+ * @since Exchange 2010
+ *
+ * @var integer
+ */
+ public $Priority;
+
+ /**
+ * Specifies the rule identifier.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $RuleId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleValidationErrorType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleValidationErrorType.php
new file mode 100644
index 00000000..ae8f625e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/RuleValidationErrorType.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\RuleValidationErrorType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single validation error on a particular rule property value,
+ * predicate property value, or action property value.
+ *
+ * @package php-ews\Type
+ */
+class RuleValidationErrorType extends Type
+{
+ /**
+ * Represents a rule validation error code that describes what failed
+ * validation for each rule predicate or action.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\RuleValidationErrorCodeType
+ */
+ public $ErrorCode;
+
+ /**
+ * Represents the reason for the validation error.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $ErrorMessage;
+
+ /**
+ * Specifies the URI to the rule field that caused the validation error.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\RuleFieldURIType
+ */
+ public $FieldUri;
+
+ /**
+ * Represents the value of the field that caused the validation error.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $FieldValue;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchExpressionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchExpressionType.php
new file mode 100644
index 00000000..6e2b31ea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchExpressionType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SearchExpressionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the substituted element within a restriction.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Determine which classes need to extend this.
+ */
+abstract class SearchExpressionType extends Type
+{
+ /**
+ * Identifies MAPI properties.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToExtendedFieldType
+ */
+ public $ExtendedFieldURI;
+
+ /**
+ * Identifies frequently referenced properties by URI.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToUnindexedFieldType
+ */
+ public $FieldURI;
+
+ /**
+ * Identifies individual members of a dictionary.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PathToIndexedFieldType
+ */
+ public $IndexedFieldURI;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchFolderType.php
new file mode 100644
index 00000000..4404f067
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchFolderType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SearchFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a search folder that is contained in a mailbox.
+ *
+ * @package php-ews\Type
+ */
+class SearchFolderType extends FolderType
+{
+ /**
+ * Contains the parameters that define a search folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchParametersType
+ */
+ public $SearchParameters;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchMailboxesResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchMailboxesResultType.php
new file mode 100644
index 00000000..4de63da8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchMailboxesResultType.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SearchMailboxesResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the result of a SearchMailboxes request.
+ *
+ * @package php-ews\Type
+ */
+class SearchMailboxesResultType extends Type
+{
+ /**
+ * Contains a list of mailboxes and associated queries for discovery search.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfMailboxQueriesType
+ */
+ public $SearchQueries;
+
+ /**
+ * Contains the type of search to perform.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SearchResultType
+ */
+ public $ResultType;
+
+ /**
+ * Specifies the total number of items in a search result.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $ItemCount;
+
+ /**
+ * Specifies the total size of one or more mailbox items.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $Size;
+
+ /**
+ * Specifies the number of pages returned in a search result pagination.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $PageItemCount;
+
+ /**
+ * Specifies the number of items to return in a search result pagination.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $PageItemSize;
+
+ /**
+ * Specifies a list of one or more KeywordStat elements.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfKeywordStatisticsSearchResultsType
+ */
+ public $KeywordStats;
+
+ /**
+ * Specifies a list of items available for preview.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSearchPreviewItemsType
+ */
+ public $Items;
+
+ /**
+ *
+ *
+ * @since Exchange 2013
+ *
+ * @var
+ */
+ public $FailedMailboxes;
+
+ /**
+ *
+ *
+ * @since Exchange 2013
+ *
+ * @var
+ */
+ public $Refiners;
+
+ /**
+ *
+ *
+ * @since Exchange 2013
+ *
+ * @var
+ */
+ public $MailboxStats;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchParametersType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchParametersType.php
new file mode 100644
index 00000000..b0493321
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchParametersType.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SearchParametersType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the parameters that define a search folder.
+ *
+ * @package php-ews\Type
+ */
+class SearchParametersType extends Type
+{
+ /**
+ * Represents the collection of folders that will be mined to determine the
+ * contents of a search folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $BaseFolderIds;
+
+ /**
+ * Represents the restriction or query that is used to filter items or
+ * folders in FindItem/FindFolder and search folder operations.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RestrictionType
+ */
+ public $Restriction;
+
+ /**
+ * Describes how a search folder traverses the folder hierarchy.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SearchFolderTraversalType
+ */
+ public $Traversal;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchPreviewItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchPreviewItemType.php
new file mode 100644
index 00000000..4c0033d9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchPreviewItemType.php
@@ -0,0 +1,221 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SearchPreviewItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an item preview for a discovery search.
+ *
+ * @package php-ews\Type
+ */
+class SearchPreviewItemType extends Type
+{
+ /**
+ * Represents a collection of recipients to receive a blind carbon copy
+ * (Bcc) of an e-mail message.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $BccRecipients;
+
+ /**
+ * Represents a collection of recipients that will receive a copy of the
+ * message.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $CcRecipients;
+
+ /**
+ * Specifies the time at which the item was created.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $CreatedTime;
+
+ /**
+ * Specifies an array of additional properties.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfExtendedPropertyType
+ */
+ public $ExtendedProperties;
+
+ /**
+ * Specifies whether the item has attachments.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $HasAttachment;
+
+ /**
+ * Specifies the identifier of the item.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $Id;
+
+ /**
+ * Describes the importance of an item or the aggregated importance of all
+ * items in a conversation in the current folder.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ImportanceChoicesType
+ */
+ public $Importance;
+
+ /**
+ * Represents the message class of an item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ItemClassType
+ */
+ public $ItemClass;
+
+ /**
+ * Contains the mailbox identifier and the user’s primary Simple Mail
+ * Transfer Protocol (SMTP) address.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\PreviewItemMailboxType
+ */
+ public $Mailbox;
+
+ /**
+ * Specifies the link to preview an item in Microsoft Outlook Web App.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $OwaLink;
+
+ /**
+ * Specifies the identifier of the parent item in a search preview.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ParentId;
+
+ /**
+ * Specifies the first 256 characters of an item for display.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Preview;
+
+ /**
+ * Indicates whether a client can read a folder or item.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $Read;
+
+ /**
+ * Specifies the time at which an item was received.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $ReceivedTime;
+
+ /**
+ * Specifies the e-mail address of the person who sent an item.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Sender;
+
+ /**
+ * Specifies the time at which the item was sent.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $SentTime;
+
+ /**
+ * Specifies the total size of one or more mailbox items.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $Size;
+
+ /**
+ * Specifies a value used for sorting.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $SortValue;
+
+ /**
+ * Represents the subject property of Exchange store items.
+ *
+ * The subject is limited to 255 characters.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Subject;
+
+ /**
+ * Specifies a list of recipients to whom the item was sent.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSmtpAddressType
+ */
+ public $ToRecipients;
+
+ /**
+ * Specifies a unique hash value used for de-duplication.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $UniqueHash;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchableMailboxType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchableMailboxType.php
new file mode 100644
index 00000000..2f095732
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SearchableMailboxType.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SearchableMailboxType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a mailbox that may be searched.
+ *
+ * @package php-ews\Type
+ */
+class SearchableMailboxType extends Type
+{
+ /**
+ * Defines the display name of the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Contains the external email address of the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ExternalEmailAddress;
+
+ /**
+ * Specifies the globally unique identifier of the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Guid;
+
+ /**
+ * Indicates whether the mailbox is external to the organization.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsExternalMailbox;
+
+ /**
+ * Specifies a Boolean value that indicates whether the entity is a
+ * distribution group or a mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsMembershipGroup;
+
+ /**
+ * Specifies the primary Simple Mail Transfer Protocol (SMTP) address of the
+ * mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $PrimarySmtpAddress;
+
+ /**
+ * Specifies the reference identifier for the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $ReferenceId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SeekToConditionPageViewType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SeekToConditionPageViewType.php
new file mode 100644
index 00000000..6424e609
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SeekToConditionPageViewType.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SeekToConditionPageViewType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the condition that is used to identify the end of a search, the
+ * starting index of a search, the maximum entries to return, and the search
+ * directions for a FindItem or FindConversation search.
+ *
+ * @package php-ews\Type
+ */
+class SeekToConditionPageViewType extends Type
+{
+ /**
+ * The text value of the BasePoint attribute is the base point from where
+ * the search will start.
+ *
+ * A text value of Beginning indicates that the search will start at the
+ * beginning of the result set. A text value of End indicates that the
+ * search will start at the end of the result set.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\IndexBasePointType
+ */
+ public $BasePoint;
+
+ /**
+ * The maximum number of items that can be returned in a result set.
+ *
+ * @since Exchange 2013
+ *
+ * @var integer
+ */
+ public $MaxEntriesReturned;
+
+ /**
+ * The condition that is used to identify the end of a search for a FindItem
+ * or a FindConversation operation.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\RestrictionType
+ */
+ public $Condition;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SendNotificationResultType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SendNotificationResultType.php
new file mode 100644
index 00000000..daf4aea1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SendNotificationResultType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SendNotificationResultType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the response of a client application to a push notification.
+ *
+ * @package php-ews\Type
+ */
+class SendNotificationResultType extends Type
+{
+ /**
+ * Describes the status of a push subscription.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SubscriptionStatusType
+ */
+ public $SubscriptionStatus;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZone.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZone.php
new file mode 100644
index 00000000..08937510
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZone.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SerializableTimeZone.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a time zone.
+ *
+ * @package php-ews\Type
+ */
+class SerializableTimeZone extends Type
+{
+ /**
+ * Represents the general offset from Coordinated Universal Time (UTC).
+ *
+ * This value is in minutes.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Bias;
+
+ /**
+ * Represents an offset from the time relative to UTC represented by the
+ * Bias (UTC) element in regions where daylight saving time is observed.
+ *
+ * This element also contains information about when the transition to
+ * daylight saving time from standard time occurs.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SerializableTimeZoneTime
+ */
+ public $DaylightTime;
+
+ /**
+ * Represents an offset from the time relative to UTC represented by the
+ * Bias (UTC) element.
+ *
+ * This element also contains information about the transition to standard
+ * time from daylight saving time in regions where daylight saving time is
+ * observed.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SerializableTimeZoneTime
+ */
+ public $StandardTime;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZoneTime.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZoneTime.php
new file mode 100644
index 00000000..a9b0f849
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializableTimeZoneTime.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SerializableTimeZoneTime.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an offset from the time relative to Coordinated Universal Time
+ * (UTC) that is represented by the Bias (UTC) element in regions where daylight
+ * saving time is observed.
+ *
+ * This class also contains information about when the transition to daylight
+ * saving time from standard time occurs.
+ *
+ * @package php-ews\Type
+ */
+class SerializableTimeZoneTime extends Type
+{
+ /**
+ * Represents the offset from the UTC offset that is identified by the Bias
+ * (UTC) element for standard time and daylight saving time.
+ *
+ * This value is in minutes.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Bias;
+
+ /**
+ * Represents the day of the week when the transition to and from standard
+ * time and daylight saving time occurs.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DayOfWeekType
+ */
+ public $DayOfWeek;
+
+ /**
+ * Represents the nth occurrence of the day that is specified in the
+ * DayOfWeek element that represents the date of transition from and to
+ * standard time and daylight saving time.
+ *
+ * The maximum value for this element can be either 4 or 5, depending on the
+ * month and year.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $DayOrder;
+
+ /**
+ * Represents the transition month of the year to and from standard time and
+ * daylight saving time.
+ *
+ * The value represents the ordinal rank of the month by occurrence and must
+ * be a number between 1 and 12
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Month;
+
+ /**
+ * Represents the transition time of day to and from standard time and
+ * daylight saving time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Create a Time class that extends DateTime.
+ */
+ public $Time;
+
+ /**
+ * Used to define a time zone that changes depending on the year.
+ *
+ * The year format is YYYY.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $Year;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializedSecurityContextType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializedSecurityContextType.php
new file mode 100644
index 00000000..24e72fb1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SerializedSecurityContextType.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SerializedSecurityContextType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines token serialization in server-to-server authentication.
+ *
+ * @package php-ews\Type
+ */
+class SerializedSecurityContextType extends Type
+{
+ /**
+ * Represents a collection of Active Directory directory service group
+ * object security identifiers.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfGroupIdentifiersType
+ */
+ public $GroupSids;
+
+ /**
+ * Represents the primary Simple Mail Transfer Protocol (SMTP) address of an
+ * account to be used for server-to-server authorization.
+ *
+ * @var string
+ */
+ public $PrimarySmtpAddress;
+
+ /**
+ * Represents the group security identifier and attributes for a restricted
+ * group.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfRestrictedGroupIdentifiersType
+ */
+ public $RestrictedGroupSids;
+
+ /**
+ * Represents the security descriptor definition language (SDDL) form of the
+ * user security identifier in a serialized security context SOAP header.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $UserSid;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServerVersionInfo.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServerVersionInfo.php
new file mode 100644
index 00000000..1536c2e9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServerVersionInfo.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ServerVersionInfo.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the Microsoft Exchange Server version number.
+ *
+ * @package php-ews\Type
+ */
+class ServerVersionInfo extends Type
+{
+ /**
+ * Describes the major build number.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MajorBuildNumber;
+
+ /**
+ * Describes the major version number.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MajorVersion;
+
+ /**
+ * Describes the minor build number.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MinorBuildNumber;
+
+ /**
+ * Describes the minor version number.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MinorVersion;
+
+ /**
+ * Describes the Exchange Web Services (EWS) schema version.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Version;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServiceConfiguration.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServiceConfiguration.php
new file mode 100644
index 00000000..deed4189
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/ServiceConfiguration.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\ServiceConfiguration.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * This "base class" is available for ErrorCode / ErrorMessage elements if those
+ * become necessary in the future.
+ *
+ * @package php-ews\Type
+ */
+class ServiceConfiguration extends Type
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetFolderFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetFolderFieldType.php
new file mode 100644
index 00000000..27eec53c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetFolderFieldType.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SetFolderFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an update that sets the value for a single property on a folder in
+ * an UpdateFolder operation.
+ *
+ * @package php-ews\Type
+ */
+class SetFolderFieldType extends FolderChangeDescriptionType
+{
+ /**
+ * Represents a folder that primarily contains calendar items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarFolderType
+ */
+ public $CalendarFolder;
+
+ /**
+ * Represents a Contacts folder in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactsFolderType
+ */
+ public $ContactsFolder;
+
+ /**
+ * Identifies a folder to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderType
+ */
+ public $Folder;
+
+ /**
+ * Represents a search folder that is contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchFolderType
+ */
+ public $SearchFolder;
+
+ /**
+ * Represents a Tasks folder that is contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TasksFolderType
+ */
+ public $TasksFolder;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetItemFieldType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetItemFieldType.php
new file mode 100644
index 00000000..bad83e2d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetItemFieldType.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SetItemFieldType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an update to a single property of an item in an UpdateItem
+ * operation.
+ *
+ * @package php-ews\Type
+ */
+class SetItemFieldType extends ItemChangeDescriptionType
+{
+ /**
+ * Represents an Exchange calendar item to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarItemType
+ */
+ public $CalendarItem;
+
+ /**
+ * Represents an Exchange contact item to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactItemType
+ */
+ public $Contact;
+
+ /**
+ * Represents a distribution list to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistributionListType
+ */
+ public $DistributionList;
+
+ /**
+ * Represents an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemType
+ */
+ public $Item;
+
+ /**
+ * Represents a meeting cancellation to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingCancellationMessageType
+ */
+ public $MeetingCancellation;
+
+ /**
+ * Represents a meeting message to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingMessageType
+ */
+ public $MeetingMessage;
+
+ /**
+ * Represents a meeting request to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingRequestMessageType
+ */
+ public $MeetingRequest;
+
+ /**
+ * Represents a meeting response to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingResponseMessageType
+ */
+ public $MeetingResponse;
+
+ /**
+ * Represents an Exchange e-mail message to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MessageType
+ */
+ public $Message;
+
+ /**
+ * Represents a post to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostItemType
+ */
+ public $PostItem;
+
+ /**
+ * Represents a task to update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TaskType
+ */
+ public $Task;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetRuleOperationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetRuleOperationType.php
new file mode 100644
index 00000000..2c67a126
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SetRuleOperationType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SetRuleOperationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an operation to update an existing rule.
+ *
+ * @package php-ews\Type
+ */
+class SetRuleOperationType extends RuleOperationType
+{
+ /**
+ * Represents a rule in a user's mailbox.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\RuleType
+ */
+ public $Rule;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SidAndAttributesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SidAndAttributesType.php
new file mode 100644
index 00000000..b1326aa8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SidAndAttributesType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SidAndAttributesType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single security identifier and attribute for an Active Directory
+ * directory service object group of which the account is a member.
+ *
+ * @package php-ews\Type
+ */
+class SidAndAttributesType extends Type
+{
+ /**
+ * Contains group attributes.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Attributes;
+
+ /**
+ * Represents the security descriptor definition language (SDDL) form of a
+ * security identifier (SID) that represents the group.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $SecurityIdentifier;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SingleRecipientType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SingleRecipientType.php
new file mode 100644
index 00000000..5249f96c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SingleRecipientType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SingleRecipientType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies the delegate in a delegate access scenario.
+ *
+ * @package php-ews\Type
+ */
+class SingleRecipientType extends Type
+{
+ /**
+ * Identifies a mail-enabled Active Directory directory service object.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\EmailAddressType
+ */
+ public $Mailbox;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseBaseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseBaseType.php
new file mode 100644
index 00000000..8ad124f0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseBaseType.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SmartResponseBaseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for smart responses.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Extend ResponseObjectType?
+ * @link https://msdn.microsoft.com/en-us/library/office/exchangewebservices.smartresponsebasetype(v=exchg.150).aspx
+ */
+class SmartResponseBaseType extends Type
+{
+ /**
+ * Represents a collection of recipients to receive a blind carbon copy
+ * (Bcc) of an e-mail.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $BccRecipients;
+
+ /**
+ * Represents the actual body content of a message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BodyType
+ */
+ public $Body;
+
+ /**
+ * Represents a collection of recipients that will receive a copy of the
+ * message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $CcRecipients;
+
+ /**
+ * Represents the address from which the message was sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $From;
+
+ /**
+ * Indicates whether the sender of an item requests a delivery receipt.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsDeliveryReceiptRequested;
+
+ /**
+ * Indicates whether the sender of an item requests a read receipt.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsReadReceiptRequested;
+
+ /**
+ * Identifies the delegate in a delegate access scenario.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $ReceivedBy;
+
+ /**
+ * Identifies the principal in a delegate access scenario.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\SingleRecipientType
+ */
+ public $ReceivedRepresenting;
+
+ /**
+ * Identifies the item to which the response object refers.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ReferenceItemId;
+
+ /**
+ * Represents the subject property of Exchange store items.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Subject;
+
+ /**
+ * Contains a set of recipients of an item.
+ *
+ * These are the primary recipients of an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType
+ */
+ public $ToRecipients;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseType.php
new file mode 100644
index 00000000..9408b43c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmartResponseType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SmartResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for smart responses that include new body content.
+ *
+ * @package php-ews\Type
+ */
+class SmartResponseType extends SmartResponseBaseType
+{
+ /**
+ * Represents the actual body content of a message.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\BodyType
+ */
+ public $NewBodyContent;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomain.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomain.php
new file mode 100644
index 00000000..d9c85157
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomain.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SmtpDomain.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single SMTP domain.
+ *
+ * @package php-ews\Type
+ */
+class SmtpDomain extends Type
+{
+ /**
+ * Identifies the name of a domain.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Indicates whether subdomains of the domain identified by the Name
+ * attribute are considered internal.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $IncludeSubdomains;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomainList.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomainList.php
new file mode 100644
index 00000000..fbac6101
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SmtpDomainList.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SmtpDomainList.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a list of internal SMTP domains of the organization.
+ *
+ * @package php-ews\Type
+ */
+class SmtpDomainList extends Type
+{
+ /**
+ * Identifies a single SMTP domain.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\SmtpDomain
+ */
+ public $Domain;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StreamingSubscriptionRequest.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StreamingSubscriptionRequest.php
new file mode 100644
index 00000000..c42cf597
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StreamingSubscriptionRequest.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\StreamingSubscriptionRequest.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a subscription to a streaming event notification subscription.
+ *
+ * @package php-ews\Type
+ */
+class StreamingSubscriptionRequest extends Type
+{
+ /**
+ * Contains a collection of event notifications that are used to create a
+ * subscription.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfNotificationEventTypesType
+ */
+ public $EventTypes;
+
+ /**
+ * Contains an array of folder identifiers that are used to identify folders
+ * to monitor for event notifications.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType
+ */
+ public $FolderIds;
+
+ /**
+ * Indicates whether the server will subscribe to all folders in the user's
+ * mailbox.
+ *
+ * A value of true indicates that the server will subscribe.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $SubscribeToAllFolders;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringArrayAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringArrayAttributedValueType.php
new file mode 100644
index 00000000..282695a8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringArrayAttributedValueType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\StringArrayAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines an instance of an array of string data.
+ *
+ * @package php-ews\Type
+ */
+class StringArrayAttributedValueType extends Type
+{
+ /**
+ * Specifies an array of attributions for its associated Value element.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfValueAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Contains the value of the extended property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringAttributedValueType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringAttributedValueType.php
new file mode 100644
index 00000000..54d90258
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringAttributedValueType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\StringAttributedValueType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an attribute associated with a persona element.
+ *
+ * @package php-ews\Type
+ */
+class StringAttributedValueType extends Type
+{
+ /**
+ * Specifies an array of attributions for the Value element.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfValueAttributionsType
+ */
+ public $Attributions;
+
+ /**
+ * Contains the value of the property.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringType.php
new file mode 100644
index 00000000..ce58fd91
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/StringType.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\StringType;
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for string types.
+ *
+ * @package php-ews\Type
+ */
+abstract class StringType extends Type
+{
+ /**
+ * Value of the element.
+ *
+ * @var string
+ */
+ public $_;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Suggestion.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Suggestion.php
new file mode 100644
index 00000000..dbbaf0df
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/Suggestion.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\Suggestion.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single meeting suggestion.
+ *
+ * @package php-ews\Type
+ */
+class Suggestion extends Type
+{
+ /**
+ * Contains an array of information that describes conflicts between users
+ * and resources and the suggested meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfAttendeeConflictData
+ */
+ public $AttendeeConflictDataArray;
+
+ /**
+ * Represents whether the suggested meeting time occurs during scheduled
+ * work hours.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsWorkTime;
+
+ /**
+ * Represents a suggested meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $MeetingTime;
+
+ /**
+ * Represents the quality of the suggested meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SuggestionQuality
+ */
+ public $SuggestionQuality;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionDayResult.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionDayResult.php
new file mode 100644
index 00000000..b7b4d6f1
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionDayResult.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SuggestionDayResult.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single day that contains suggested meeting times.
+ *
+ * @package php-ews\Type
+ */
+class SuggestionDayResult extends Type
+{
+ /**
+ * Represents the date that contains the suggested meeting times.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $Date;
+
+ /**
+ * Represents the quality of the day for containing quality suggested
+ * meeting times.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SuggestionQuality
+ */
+ public $DayQuality;
+
+ /**
+ * Contains an array of meeting suggestions.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSuggestion
+ */
+ public $SuggestionArray;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsResponseType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsResponseType.php
new file mode 100644
index 00000000..b1884c91
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsResponseType.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SuggestionsResponseType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents response status information and suggestion data for requested
+ * meeting suggestions.
+ *
+ * @package php-ews\Type
+ */
+class SuggestionsResponseType extends Type
+{
+ /**
+ * Provides descriptive information about the response status.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Response\ResponseMessageType
+ */
+ public $ResponseMessage;
+
+ /**
+ * Contains an array of meeting suggestions organized by date.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfSuggestionDayResult
+ */
+ public $SuggestionDayResultArray;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsViewOptionsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsViewOptionsType.php
new file mode 100644
index 00000000..a1e03275
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuggestionsViewOptionsType.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SuggestionsViewOptionsType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the options for obtaining meeting suggestion information.
+ *
+ * @package php-ews\Type
+ */
+class SuggestionsViewOptionsType extends Type
+{
+ /**
+ * Represents the start time of a meeting that you want to update with the
+ * suggested meeting time results.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $CurrentMeetingTime;
+
+ /**
+ * Identifies the time span that is queried for detailed information about
+ * suggested meeting times.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\Duration
+ */
+ public $DetailedSuggestionsWindow;
+
+ /**
+ * This element is not used.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $GlobalObjectId;
+
+ /**
+ * Specifies the percentage of attendees that must have the time period open
+ * for the time period to qualify as a good suggested meeting time.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $GoodThreshold;
+
+ /**
+ * Specifies the number of suggested results for meeting times outside
+ * regular working hours per day.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MaximumNonWorkHourResultsByDay;
+
+ /**
+ * Specifies the number of suggested meeting times per day returned in the
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MaximumResultsByDay;
+
+ /**
+ * Specifies the length of the meeting to be suggested.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $MeetingDurationInMinutes;
+
+ /**
+ * Specifies the quality of meeting suggestions to be returned in the
+ * response.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\SuggestionQuality
+ */
+ public $MinimumSuggestionQuality;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuppressReadReceiptType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuppressReadReceiptType.php
new file mode 100644
index 00000000..841c615c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SuppressReadReceiptType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SuppressReadReceiptType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Used to suppress read receipts.
+ *
+ * @package php-ews\Type
+ */
+class SuppressReadReceiptType extends ReferenceItemResponseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyChangesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyChangesType.php
new file mode 100644
index 00000000..06b1e6b0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyChangesType.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SyncFolderHierarchyChangesType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a sequenced array of change types that represent the type of
+ * differences between the folders on the client and the folders on the computer
+ * that is running Microsoft Exchange Server 2007.
+ *
+ * @package php-ews\Type
+ */
+class SyncFolderHierarchyChangesType extends Type
+{
+ /**
+ * Identifies a single folder to create in the local client store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderHierarchyCreateOrUpdateType
+ */
+ public $Create;
+
+ /**
+ * Identifies a single folder to delete in the local client store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderHierarchyDeleteType
+ */
+ public $Delete;
+
+ /**
+ * Identifies a single folder to update in the local client store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderHierarchyCreateOrUpdateType
+ */
+ public $Update;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyCreateOrUpdateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyCreateOrUpdateType.php
new file mode 100644
index 00000000..a46932aa
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyCreateOrUpdateType.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SyncFolderHierarchyCreateOrUpdateType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a single folder to create in the local client store.
+ *
+ * @package php-ews\Type
+ */
+class SyncFolderHierarchyCreateOrUpdateType extends Type
+{
+ /**
+ * Represents a folder that primarily contains calendar items.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarFolderType
+ */
+ public $CalendarFolder;
+
+ /**
+ * Represents a contact folder in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactsFolderType
+ */
+ public $ContactsFolder;
+
+ /**
+ * Defines the folder to create, get, find, synchronize, or update.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderType
+ */
+ public $Folder;
+
+ /**
+ * Represents a search folder contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SearchFolderType
+ */
+ public $SearchFolder;
+
+ /**
+ * Represents a task folder contained in a mailbox.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TasksFolderType
+ */
+ public $TasksFolder;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyDeleteType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyDeleteType.php
new file mode 100644
index 00000000..f0a8edd4
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderHierarchyDeleteType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SyncFolderHierarchyDeleteType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a single folder to delete in the local client store.
+ *
+ * @package php-ews\Type
+ */
+class SyncFolderHierarchyDeleteType extends Type
+{
+ /**
+ * Contains the identifier and change key of a folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $FolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsChangesType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsChangesType.php
new file mode 100644
index 00000000..46713e5d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsChangesType.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SyncFolderItemsChangesType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a sequence array of change types that represent the types of
+ * differences between the items on the client and the items on the Exchange
+ * server.
+ *
+ * @package php-ews\Type
+ */
+class SyncFolderItemsChangesType extends Type
+{
+ /**
+ * Identifies a single item to create in the local client store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderItemsCreateOrUpdateType[]
+ */
+ public $Create = array();
+
+ /**
+ * Identifies a single item to delete in the local client store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderItemsDeleteType[]
+ */
+ public $Delete = array();
+
+ /**
+ * Returned in SyncFolderItems operation responses when an item has been
+ * read.
+ *
+ * This property is read-only.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderItemsReadFlagType[]
+ */
+ public $ReadFlagChange = array();
+
+ /**
+ * Identifies a single item to update in the local client store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SyncFolderItemsCreateOrUpdateType[]
+ */
+ public $Update = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsCreateOrUpdateType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsCreateOrUpdateType.php
new file mode 100644
index 00000000..3220b983
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsCreateOrUpdateType.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SyncFolderItemsCreateOrUpdateType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a single item to create in the local client store.
+ *
+ * @package php-ews\Type
+ */
+class SyncFolderItemsCreateOrUpdateType extends Type
+{
+ /**
+ * Represents an Exchange calendar item to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\CalendarItemType
+ */
+ public $CalendarItem;
+
+ /**
+ * Represents an Exchange contact item to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ContactItemType
+ */
+ public $Contact;
+
+ /**
+ * Represents a distribution list to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistributionListType
+ */
+ public $DistributionList;
+
+ /**
+ * Represents a generic Exchange item to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemType
+ */
+ public $Item;
+
+ /**
+ * Represents a meeting cancellation to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingCancellationMessageType
+ */
+ public $MeetingCancellation;
+
+ /**
+ * Represents a meeting message to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingMessageType
+ */
+ public $MeetingMessage;
+
+ /**
+ * Represents a meeting request to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingRequestMessageType
+ */
+ public $MeetingRequest;
+
+ /**
+ * Represents a meeting response to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MeetingResponseMessageType
+ */
+ public $MeetingResponse;
+
+ /**
+ * Represents an Exchange e-mail message to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MessageType
+ */
+ public $Message;
+
+ /**
+ * Represents an Exchange post to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\PostItemType
+ */
+ public $PostItem;
+
+ /**
+ * Represents a task to create.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TaskType
+ */
+ public $Task;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsDeleteType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsDeleteType.php
new file mode 100644
index 00000000..3f0536e6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsDeleteType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SyncFolderItemsDeleteType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a single item to delete in the local client store.
+ *
+ * @package php-ews\Type
+ */
+class SyncFolderItemsDeleteType extends Type
+{
+ /**
+ * Contains the unique identifier and change key of an item in the Exchange store.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsReadFlagType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsReadFlagType.php
new file mode 100644
index 00000000..87c51de3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/SyncFolderItemsReadFlagType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\SyncFolderItemsReadFlagType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies whether or not an item has been read.
+ *
+ * @package php-ews\Type
+ */
+class SyncFolderItemsReadFlagType extends Type
+{
+ /**
+ * Indicates whether the read-flag has been set to true.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsRead;
+
+ /**
+ * Identifies the item for which the read-flag has been changed.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TargetFolderIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TargetFolderIdType.php
new file mode 100644
index 00000000..d4b0219e
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TargetFolderIdType.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TargetFolderIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Indicates the folder that is targeted for actions that use folders.
+ *
+ * @package php-ews\Type
+ */
+class TargetFolderIdType extends Type
+{
+ /**
+ * Specifies the identifier of an address list.
+ *
+ * @since Exchange 2013
+ *
+ * @var \jamesiarmes\PhpEws\Type\AddressListIdType
+ */
+ public $AddressListId;
+
+ /**
+ * Identifies folders that can be referenced by name.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DistinguishedFolderIdType
+ */
+ public $DistinguishedFolderId;
+
+ /**
+ * Contains the identifier and change key of the context folder.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $FolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskRecurrenceType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskRecurrenceType.php
new file mode 100644
index 00000000..7795713d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskRecurrenceType.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TaskRecurrenceType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the recurrence pattern for recurring tasks.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Implement TaskRecurrencePatternTypes trait.
+ * @todo Implement RecurrenceRangeTypes trait.
+ */
+class TaskRecurrenceType extends RecurrenceType
+{
+ /**
+ * Describes how many days after the completion of the current task the next
+ * occurrence will be due.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\DailyRegeneratingPatternType
+ */
+ public $DailyRegeneration;
+
+ /**
+ * Describes how many months after the completion of the current task the
+ * next occurrence will be due.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\MonthlyRegeneratingPatternType
+ */
+ public $MonthlyRegeneration;
+
+ /**
+ * Describes how many weeks after the completion of the current task the
+ * next occurrence will be due.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\WeeklyRegeneratingPatternType
+ */
+ public $WeeklyRegeneration;
+
+ /**
+ * Describes how many years after the completion of the current task the
+ * next occurrence will be due.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\YearlyRegeneratingPatternType
+ */
+ public $YearlyRegeneration;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskType.php
new file mode 100644
index 00000000..7d23fed8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TaskType.php
@@ -0,0 +1,243 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TaskType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a task in the Exchange store.
+ *
+ * @package php-ews\Type
+ */
+class TaskType extends ItemType
+{
+ /**
+ * Represents the actual amount of time that is spent on a task.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $ActualWork;
+
+ /**
+ * Represents the time when a task is assigned to a contact.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $AssignedTime;
+
+ /**
+ * Holds billing information for a task.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $BillingInformation;
+
+ /**
+ * Specifies the version of the task.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $ChangeCount;
+
+ /**
+ * Represents the collection of companies that are associated with a contact
+ * or task.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Companies;
+
+ /**
+ * Represents the date on which a task is completed.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $CompleteDate;
+
+ /**
+ * Contains a list of contacts that are associated with a task.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfStringsType
+ */
+ public $Contacts;
+
+ /**
+ * Represents the status of a delegated task.
+ *
+ * This is a read-only property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\TaskDelegateStateType
+ */
+ public $DelegationState;
+
+ /**
+ * Contains the name of the delegator who assigned the task.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Delegator;
+
+ /**
+ * Represents the date when a task item is due.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $DueDate;
+
+ /**
+ * Indicates whether the task is editable or not.
+ *
+ * The following values are possible:
+ * - 0: The default for all task items.
+ * - 1: A task request.
+ * - 2: A task acceptance from a recipient of a task request.
+ * - 3: A task declination from a recipient of a task request.
+ * - 4: An update to a previous task request.
+ * - 5: Not used.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $IsAssignmentEditable;
+
+ /**
+ * Indicates whether the task has been completed or not.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsComplete;
+
+ /**
+ * Indicates whether a task is part of a recurring item.
+ *
+ * This element is read-only.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsRecurring;
+
+ /**
+ * Indicates whether the task is owned by a team or not.
+ *
+ * @since Exchange 2007
+ *
+ * @var boolean
+ */
+ public $IsTeamTask;
+
+ /**
+ * Represents mileage for a task item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Mileage;
+
+ /**
+ * Represents the owner of a task.
+ *
+ * This is a read-only property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $Owner;
+
+ /**
+ * Describes the completion status of a task.
+ *
+ * @since Exchange 2007
+ *
+ * @var float
+ */
+ public $PercentComplete;
+
+ /**
+ * Contains recurrence information for recurring tasks.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RecurrenceType
+ */
+ public $Recurrence;
+
+ /**
+ * Represents the start date of a task item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a DateTime object.
+ */
+ public $StartDate;
+
+ /**
+ * Represents the status of a task item.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\TaskStatusType
+ */
+ public $Status;
+
+ /**
+ * Contains an explanation of the task status.
+ *
+ * This is a read-only property.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $StatusDescription;
+
+ /**
+ * Contains a description of how much work is associated with an item.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $TotalWork;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TasksFolderType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TasksFolderType.php
new file mode 100644
index 00000000..5039a838
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TasksFolderType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TasksFolderType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a Tasks folder that is contained in a mailbox.
+ *
+ * @package php-ews\Type
+ */
+class TasksFolderType extends FolderType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TentativelyAcceptItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TentativelyAcceptItemType.php
new file mode 100644
index 00000000..a729262c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TentativelyAcceptItemType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TentativelyAcceptItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a Tentative reply to a meeting request.
+ *
+ * @package php-ews\Type
+ */
+class TentativelyAcceptItemType extends WellKnownResponseObjectType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeChangeType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeChangeType.php
new file mode 100644
index 00000000..f0312b58
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeChangeType.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TimeChangeType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the date and time when a time change occurs.
+ *
+ * @package php-ews\Type
+ */
+class TimeChangeType extends Type
+{
+ /**
+ * Represents the date when the time changes from standard time or daylight
+ * saving time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a Date object that extends DateTime.
+ */
+ public $AbsoluteDate;
+
+ /**
+ * Describes the offset from the BaseOffset.
+ *
+ * Together with the BaseOffset element, the Offset element identifies
+ * whether the time is standard time or daylight saving time.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $Offset;
+
+ /**
+ * Describes a relative yearly recurrence pattern for a time zone transition
+ * date.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\RelativeYearlyRecurrencePatternType
+ */
+ public $RelativeYearlyRecurrence;
+
+ /**
+ * Describes the time when the time changes between standard time and
+ * daylight saving time.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @todo Make a Time object that extends DateTime.
+ */
+ public $Time;
+
+ /**
+ * Name of the time zone.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $TimeZoneName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneContextType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneContextType.php
new file mode 100644
index 00000000..14d8aa93
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneContextType.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TimeZoneContextType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the time zone definition that is to be used as the default when
+ * assigning the time zone for the DateTime properties of objects that are
+ * created, updated, and retrieved by using Exchange Web Services (EWS).
+ *
+ * @package php-ews\Type
+ */
+class TimeZoneContextType extends Type
+{
+ /**
+ * Specifies the periods and transitions that define a time zone.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType
+ */
+ public $TimeZoneDefinition;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneDefinitionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneDefinitionType.php
new file mode 100644
index 00000000..bceb3cab
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneDefinitionType.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TimeZoneDefinitionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a timezone.
+ *
+ * @package php-ews\Type
+ */
+class TimeZoneDefinitionType extends Type
+{
+ /**
+ * Unique identifier of the time zone definition.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Id;
+
+ /**
+ * Descriptive name of the time zone definition.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Array of Period elements that define the time offset at different stages
+ * of the time zone.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfPeriodsType
+ */
+ public $Periods;
+
+ /**
+ * Array of time zone transitions.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTransitionsType
+ */
+ public $Transitions;
+
+ /**
+ * Array of TransitionsGroup elements that specify time zone transitions.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfTransitionsGroupsType
+ */
+ public $TransitionsGroups;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneType.php
new file mode 100644
index 00000000..7f9dcf1c
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TimeZoneType.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TimeZoneType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a time zone.
+ *
+ * @package php-ews\Type
+ */
+class TimeZoneType extends Type
+{
+ /**
+ * Represents the hourly offset from UTC for the current time zone.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $BaseOffset;
+
+ /**
+ * Represents the date and time when the time changes from standard time to
+ * daylight saving time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeChangeType
+ */
+ public $Daylight;
+
+ /**
+ * Represents the date and time when the time changes from daylight saving
+ * time to standard time.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\TimeChangeType
+ */
+ public $Standard;
+
+ /**
+ * The name of the time zone.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ */
+ public $TimeZoneName;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TooBigGroupAttendeeConflictData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TooBigGroupAttendeeConflictData.php
new file mode 100644
index 00000000..a8ca9d46
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TooBigGroupAttendeeConflictData.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TooBigGroupAttendeeConflictData.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an attendee that was resolved as a distribution list but the
+ * distribution list was too large to expand.
+ *
+ * @package php-ews\Type
+ */
+class TooBigGroupAttendeeConflictData extends AttendeeConflictData
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TrackingPropertyType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TrackingPropertyType.php
new file mode 100644
index 00000000..61bdf1b8
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TrackingPropertyType.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TrackingPropertyType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a name and value pair of strings that is used to create properties
+ * for message tracking reports.
+ *
+ * @package php-ews\Type
+ */
+class TrackingPropertyType extends Type
+{
+ /**
+ * Defines a name for the message tracking report property.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $Name;
+
+ /**
+ * Defines a value for the message tracking report property.
+ *
+ * This element is optional.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ */
+ public $Value;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionTargetType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionTargetType.php
new file mode 100644
index 00000000..d37695b0
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionTargetType.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TransitionTargetType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Specifies the target of the time zone transition.
+ *
+ * The target is either a time zone period or a group of time zone transitions.
+ *
+ * @package php-ews\Type
+ */
+class TransitionTargetType extends StringType
+{
+ /**
+ * Indicates whether the time zone transition target is a time zone period
+ * or of a group of time zone transitions.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\TransitionTargetKindType
+ */
+ public $Kind;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionType.php
new file mode 100644
index 00000000..23bc486d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TransitionType.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TransitionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a time zone transition.
+ *
+ * @package php-ews\Type
+ *
+ * @todo Alter RecurringDateTransitionType to extend this class.
+ */
+class TransitionType extends Type
+{
+ /**
+ * Specifies the Period or TransitionsGroup that is the target of the time
+ * zone transition.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\TransitionTargetType
+ */
+ public $To;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TwoOperandExpressionType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TwoOperandExpressionType.php
new file mode 100644
index 00000000..ecfcc665
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/TwoOperandExpressionType.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\TwoOperandExpressionType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class for search expressions with two operands.
+ *
+ * @package php-ews\Type
+ */
+abstract class TwoOperandExpressionType extends SearchExpressionType
+{
+ /**
+ * Represents either a property or a constant value to be used when
+ * comparing with another property.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\FieldURIOrConstantType
+ */
+ public $FieldURIOrConstant;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnifiedMessageServiceConfiguration.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnifiedMessageServiceConfiguration.php
new file mode 100644
index 00000000..f5efd960
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnifiedMessageServiceConfiguration.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UnifiedMessageServiceConfiguration.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents service configuration information for the Unified Messaging
+ * service.
+ *
+ * @package php-ews\Type
+ */
+class UnifiedMessageServiceConfiguration extends ServiceConfiguration
+{
+ /**
+ * Identifies the Play-on-Phone dial string.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $PlayOnPhoneDialString;
+
+ /**
+ * Indicates whether the Play-on-Phone feature is enabled.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $PlayOnPhoneEnabled;
+
+ /**
+ * Indicates whether Unified Messaging is enabled for an account.
+ *
+ * This element is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var boolean
+ */
+ public $UmEnabled;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnknownAttendeeConflictData.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnknownAttendeeConflictData.php
new file mode 100644
index 00000000..431677ea
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UnknownAttendeeConflictData.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UnknownAttendeeConflictData.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents an unresolvable attendee or an attendee that is not a user,
+ * distribution list, or contact.
+ *
+ * @package php-ews\Type
+ */
+class UnknownAttendeeConflictData extends AttendeeConflictData
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UploadItemType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UploadItemType.php
new file mode 100644
index 00000000..ba3a2c80
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UploadItemType.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UploadItemType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a single item to upload into a mailbox.
+ *
+ * @package php-ews\Type
+ */
+class UploadItemType extends Type
+{
+ /**
+ * Specifies the action for uploading an item into a mailbox.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\CreateActionType
+ */
+ public $CreateAction;
+
+ /**
+ * Contains the data of a single item to upload into a mailbox.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $Data;
+
+ /**
+ * Specifies whether the uploaded item is a folder associated item.
+ *
+ * A value of true indicates that the item is a folder associated item.
+ *
+ * This attribute is optional.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var boolean
+ */
+ public $IsAssociated;
+
+ /**
+ * Contains the unique identifier and change key of an item to create or
+ * update in the Exchange store.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Represents the identifier of the parent folder where a new item is
+ * created or that contains the item to update.
+ *
+ * @since Exchange 2010 SP1
+ *
+ * @var \jamesiarmes\PhpEws\Type\FolderIdType
+ */
+ public $ParentFolderId;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryEntryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryEntryType.php
new file mode 100644
index 00000000..5fad0cc3
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryEntryType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserConfigurationDictionaryEntryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the contents of a single dictionary entry property.
+ *
+ * @package php-ews\Type
+ */
+class UserConfigurationDictionaryEntryType extends Type
+{
+ /**
+ * Specifies the dictionary key for a dictionary property.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationDictionaryObjectType
+ */
+ public $DictionaryKey;
+
+ /**
+ * Specifies the dictionary value for a dictionary property.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationDictionaryObjectType
+ */
+ public $DictionaryValue;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryObjectType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryObjectType.php
new file mode 100644
index 00000000..9c771ff2
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryObjectType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserConfigurationDictionaryObjectType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the value of a dictionary property.
+ *
+ * @package php-ews\Type
+ */
+class UserConfigurationDictionaryObjectType extends Type
+{
+ /**
+ * Specifies the dictionary object type.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\UserConfigurationDictionaryObjectTypesType
+ */
+ public $Type;
+
+ /**
+ * Specifies the dictionary object value as a string.ß
+ *
+ * @since Exchange 2010
+ *
+ * @var string[]
+ */
+ public $Value = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryType.php
new file mode 100644
index 00000000..b7bf4991
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationDictionaryType.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserConfigurationDictionaryType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a set of dictionary property entries for a user configuration object.
+ *
+ * @package php-ews\Type
+ */
+class UserConfigurationDictionaryType extends Type
+{
+ /**
+ * Specifies the contents of a single dictionary entry property.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationDictionaryEntryType[]
+ */
+ public $DictionaryEntry = array();
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationNameType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationNameType.php
new file mode 100644
index 00000000..b8031c84
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationNameType.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserConfigurationNameType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the name of a user configuration object. The user configuration
+ * object name is the identifier for a user configuration object.
+ *
+ * @package php-ews\Type
+ */
+class UserConfigurationNameType extends TargetFolderIdType
+{
+ /**
+ * The name of a user configuration object.
+ *
+ * This attribute is required.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $Name;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationType.php
new file mode 100644
index 00000000..9cf068e9
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserConfigurationType.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserConfigurationType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines a single user configuration object.
+ *
+ * @package php-ews\Type
+ */
+class UserConfigurationType extends Type
+{
+ /**
+ * Contains binary data property content for a user configuration object.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $BinaryData;
+
+ /**
+ * Defines a set of dictionary property entries for a user configuration
+ * object.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationDictionaryType
+ */
+ public $Dictionary;
+
+ /**
+ * Defines the user configuration object item identifier.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\ItemIdType
+ */
+ public $ItemId;
+
+ /**
+ * Represents the name of a user configuration object.
+ *
+ * This element must be used when you create a user configuration object.
+ *
+ * @since Exchange 2010
+ *
+ * @var \jamesiarmes\PhpEws\Type\UserConfigurationNameType
+ */
+ public $UserConfigurationName;
+
+ /**
+ * Contains XML data property content for a user configuration object.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @todo Create a base64 class?
+ */
+ public $XmlData;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserIdType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserIdType.php
new file mode 100644
index 00000000..5691d959
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserIdType.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserIdType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Identifies a delegate user or a user who has folder access permissions.
+ *
+ * @package php-ews\Type
+ */
+class UserIdType extends Type
+{
+ /**
+ * Defines the display name of a folder, contact, distribution list, or
+ * delegate user.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $DisplayName;
+
+ /**
+ * Identifies Anonymous and Default user accounts for delegate access.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DistinguishedUserType
+ */
+ public $DistinguishedUser;
+
+ /**
+ * Identifies an external delegate user or an external user who has folder
+ * access permissions.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ */
+ public $ExternalUserIdentity;
+
+ /**
+ * Represents the primary Simple Mail Transfer Protocol (SMTP) address of an
+ * account to be used for delegate access.
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $PrimarySmtpAddress;
+
+ /**
+ * Represents the security descriptor definition language (SDDL) form of the
+ * security identifier (SID).
+ *
+ * @since Exchange 2007 SP1
+ *
+ * @var string
+ */
+ public $SID;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserMailboxType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserMailboxType.php
new file mode 100644
index 00000000..918774d6
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserMailboxType.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserMailboxType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents a user mailbox.
+ *
+ * @package php-ews\Type
+ */
+class UserMailboxType extends Type
+{
+ /**
+ * The text value of the Id attribute is the identifier of the mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var string
+ */
+ public $Id;
+
+ /**
+ * Whether the mailbox is an archive mailbox.
+ *
+ * @since Exchange 2013
+ *
+ * @var boolean
+ */
+ public $IsArchive;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserOofSettings.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserOofSettings.php
new file mode 100644
index 00000000..bfecf7d5
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/UserOofSettings.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\UserOofSettings.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Defines the Out of Office (OOF) settings.
+ *
+ * @package php-ews\Type
+ */
+class UserOofSettings extends Type
+{
+ /**
+ * Contains the duration for which the OOF status is enabled if the OofState
+ * element is set to Scheduled.
+ *
+ * If the OofState element is set to Enabled or Disabled, the value of this
+ * element is ignored.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\Duration
+ */
+ public $Duration;
+
+ /**
+ * Contains a value that determines to whom external OOF messages are sent.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\ExternalAudience
+ */
+ public $ExternalAudience;
+
+ /**
+ * Contains the OOF response sent to addresses outside the recipient's
+ * domain or trusted domains.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReplyBody
+ */
+ public $ExternalReply;
+
+ /**
+ * Contains the OOF response sent to other users in the user's domain or
+ * trusted domain.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\ReplyBody
+ */
+ public $InternalReply;
+
+ /**
+ * Contains the user's OOF state.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\OofState
+ */
+ public $OofState;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRecurrencePatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRecurrencePatternType.php
new file mode 100644
index 00000000..86c30c8b
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRecurrencePatternType.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\WeeklyRecurrencePatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes a weekly recurrence pattern.
+ *
+ * @package php-ews\Type
+ */
+class WeeklyRecurrencePatternType extends IntervalRecurrencePatternBaseType
+{
+ /**
+ * Describes which days of the week are in the weekly recurrence pattern.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DaysOfWeekType
+ */
+ public $DaysOfWeek;
+
+ /**
+ * Specifies the first day of the week.
+ *
+ * @since Exchange 2010
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DayOfWeekType
+ */
+ public $FirstDayOfWeek;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRegeneratingPatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRegeneratingPatternType.php
new file mode 100644
index 00000000..2d752210
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WeeklyRegeneratingPatternType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\WeeklyRegeneratingPatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the frequency, in weeks, in which a task is regenerated.
+ *
+ * @package php-ews\Type
+ */
+class WeeklyRegeneratingPatternType extends RegeneratingPatternBaseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WellKnownResponseObjectType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WellKnownResponseObjectType.php
new file mode 100644
index 00000000..f659cbeb
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WellKnownResponseObjectType.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\WellKnownResponseObjectType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Base class fot meeting request replies.
+ *
+ * @package php-ews\Type
+ */
+abstract class WellKnownResponseObjectType extends ResponseObjectType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingHours.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingHours.php
new file mode 100644
index 00000000..da9fc282
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingHours.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\WorkingHours.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the time zone settings and working hours for the requested mailbox
+ * user.
+ *
+ * @package php-ews\Type
+ */
+class WorkingHours extends Type
+{
+ /**
+ * Contains elements that identify time zone information.
+ *
+ * This element also contains information about the transition between
+ * standard time and daylight saving time.
+ *
+ * This element is required if the WorkingHours element is used.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\Type\SerializableTimeZone
+ */
+ public $TimeZone;
+
+ /**
+ * Contains working period information for the mailbox user.
+ *
+ * This element is required if the WorkingHours element is used.
+ *
+ * @since Exchange 2007
+ *
+ * @var \jamesiarmes\PhpEws\ArrayType\ArrayOfWorkingPeriod
+ */
+ public $WorkingPeriodArray;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingPeriod.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingPeriod.php
new file mode 100644
index 00000000..1375234d
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/WorkingPeriod.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\WorkingPeriod.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+use \jamesiarmes\PhpEws\Type;
+
+/**
+ * Represents the work week days and hours of the mailbox user.
+ *
+ * @package php-ews\Type
+ */
+class WorkingPeriod extends Type
+{
+ /**
+ * Contains the list of working days scheduled for the mailbox user.
+ *
+ * @since Exchange 2007
+ *
+ * @var string
+ *
+ * @see \jamesiarmes\PhpEws\Enumeration\DaysOfWeekType
+ */
+ public $DayOfWeek;
+
+ /**
+ * Represents the end of the working day for a mailbox user.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $EndTimeInMinutes;
+
+ /**
+ * Represents the start of the working day for a mailbox user.
+ *
+ * @since Exchange 2007
+ *
+ * @var integer
+ */
+ public $StartTimeInMinutes;
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/YearlyRegeneratingPatternType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/YearlyRegeneratingPatternType.php
new file mode 100644
index 00000000..7381d89f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/Type/YearlyRegeneratingPatternType.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Contains \jamesiarmes\PhpEws\Type\YearlyRegeneratingPatternType.
+ */
+
+namespace jamesiarmes\PhpEws\Type;
+
+/**
+ * Describes the frequency, in years, in which a task is regenerated.
+ *
+ * @package php-ews\Type
+ */
+class YearlyRegeneratingPatternType extends RegeneratingPatternBaseType
+{
+
+}
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/messages.xsd b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/messages.xsd
new file mode 100644
index 00000000..de89495f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/messages.xsd
@@ -0,0 +1,4523 @@
+<xs:schema id="messages"
+ elementFormDefault="qualified"
+ xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
+ xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://schemas.microsoft.com/exchange/services/2006/messages">
+ <!-- Import common types. -->
+ <xs:import namespace="http://schemas.microsoft.com/exchange/services/2006/types" schemaLocation="types.xsd"/>
+ <!-- Basic response type -->
+ <!-- Common to all responses -->
+ <xs:simpleType name="ResponseCodeType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents the message keys that can be returned by response error messages
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NoError"/>
+ <xs:enumeration value="ErrorAccessDenied"/>
+ <xs:enumeration value="ErrorAccessModeSpecified"/>
+ <xs:enumeration value="ErrorAccountDisabled"/>
+ <xs:enumeration value="ErrorAddDelegatesFailed"/>
+ <xs:enumeration value="ErrorAddressSpaceNotFound"/>
+ <xs:enumeration value="ErrorADOperation"/>
+ <xs:enumeration value="ErrorADSessionFilter"/>
+ <xs:enumeration value="ErrorADUnavailable"/>
+ <xs:enumeration value="ErrorAutoDiscoverFailed"/>
+ <xs:enumeration value="ErrorAffectedTaskOccurrencesRequired"/>
+ <xs:enumeration value="ErrorAttachmentNestLevelLimitExceeded" />
+ <xs:enumeration value="ErrorAttachmentSizeLimitExceeded"/>
+ <xs:enumeration value="ErrorArchiveFolderPathCreation"/>
+ <xs:enumeration value="ErrorArchiveMailboxNotEnabled"/>
+ <xs:enumeration value="ErrorArchiveMailboxServiceDiscoveryFailed"/>
+ <xs:enumeration value="ErrorAvailabilityConfigNotFound"/>
+ <xs:enumeration value="ErrorBatchProcessingStopped"/>
+ <xs:enumeration value="ErrorCalendarCannotMoveOrCopyOccurrence"/>
+ <xs:enumeration value="ErrorCalendarCannotUpdateDeletedItem"/>
+ <xs:enumeration value="ErrorCalendarCannotUseIdForOccurrenceId"/>
+ <xs:enumeration value="ErrorCalendarCannotUseIdForRecurringMasterId"/>
+ <xs:enumeration value="ErrorCalendarDurationIsTooLong"/>
+ <xs:enumeration value="ErrorCalendarEndDateIsEarlierThanStartDate"/>
+ <xs:enumeration value="ErrorCalendarFolderIsInvalidForCalendarView"/>
+ <xs:enumeration value="ErrorCalendarInvalidAttributeValue"/>
+ <xs:enumeration value="ErrorCalendarInvalidDayForTimeChangePattern"/>
+ <xs:enumeration value="ErrorCalendarInvalidDayForWeeklyRecurrence"/>
+ <xs:enumeration value="ErrorCalendarInvalidPropertyState"/>
+ <xs:enumeration value="ErrorCalendarInvalidPropertyValue"/>
+ <xs:enumeration value="ErrorCalendarInvalidRecurrence"/>
+ <xs:enumeration value="ErrorCalendarInvalidTimeZone"/>
+ <xs:enumeration value="ErrorCalendarIsCancelledForAccept"/>
+ <xs:enumeration value="ErrorCalendarIsCancelledForDecline"/>
+ <xs:enumeration value="ErrorCalendarIsCancelledForRemove"/>
+ <xs:enumeration value="ErrorCalendarIsCancelledForTentative"/>
+ <xs:enumeration value="ErrorCalendarIsDelegatedForAccept"/>
+ <xs:enumeration value="ErrorCalendarIsDelegatedForDecline"/>
+ <xs:enumeration value="ErrorCalendarIsDelegatedForRemove"/>
+ <xs:enumeration value="ErrorCalendarIsDelegatedForTentative"/>
+ <xs:enumeration value="ErrorCalendarIsNotOrganizer"/>
+ <xs:enumeration value="ErrorCalendarIsOrganizerForAccept"/>
+ <xs:enumeration value="ErrorCalendarIsOrganizerForDecline"/>
+ <xs:enumeration value="ErrorCalendarIsOrganizerForRemove"/>
+ <xs:enumeration value="ErrorCalendarIsOrganizerForTentative"/>
+ <xs:enumeration value="ErrorCalendarOccurrenceIndexIsOutOfRecurrenceRange"/>
+ <xs:enumeration value="ErrorCalendarOccurrenceIsDeletedFromRecurrence"/>
+ <xs:enumeration value="ErrorCalendarOutOfRange"/>
+ <xs:enumeration value="ErrorCalendarMeetingRequestIsOutOfDate"/>
+ <xs:enumeration value="ErrorCalendarViewRangeTooBig"/>
+ <xs:enumeration value="ErrorCallerIsInvalidADAccount"/>
+ <xs:enumeration value="ErrorCannotAccessDeletedPublicFolder"/>
+ <xs:enumeration value="ErrorCannotArchiveCalendarContactTaskFolderException"/>
+ <xs:enumeration value="ErrorCannotArchiveItemsInPublicFolders"/>
+ <xs:enumeration value="ErrorCannotArchiveItemsInArchiveMailbox"/>
+ <xs:enumeration value="ErrorCannotCreateCalendarItemInNonCalendarFolder"/>
+ <xs:enumeration value="ErrorCannotCreateContactInNonContactFolder"/>
+ <xs:enumeration value="ErrorCannotCreatePostItemInNonMailFolder"/>
+ <xs:enumeration value="ErrorCannotCreateTaskInNonTaskFolder"/>
+ <xs:enumeration value="ErrorCannotDeleteObject"/>
+ <xs:enumeration value="ErrorCannotDisableMandatoryExtension"/>
+ <xs:enumeration value="ErrorCannotFindUser"/>
+ <xs:enumeration value="ErrorCannotGetSourceFolderPath"/>
+ <xs:enumeration value="ErrorCannotGetExternalEcpUrl"/>
+ <xs:enumeration value="ErrorCannotOpenFileAttachment"/>
+ <xs:enumeration value="ErrorCannotDeleteTaskOccurrence"/>
+ <xs:enumeration value="ErrorCannotEmptyFolder"/>
+ <xs:enumeration value="ErrorCannotSetCalendarPermissionOnNonCalendarFolder"/>
+ <xs:enumeration value="ErrorCannotSetNonCalendarPermissionOnCalendarFolder"/>
+ <xs:enumeration value="ErrorCannotSetPermissionUnknownEntries"/>
+ <xs:enumeration value="ErrorCannotSpecifySearchFolderAsSourceFolder"/>
+ <xs:enumeration value="ErrorCannotUseFolderIdForItemId"/>
+ <xs:enumeration value="ErrorCannotUseItemIdForFolderId"/>
+ <xs:enumeration value="ErrorChangeKeyRequired"/>
+ <xs:enumeration value="ErrorChangeKeyRequiredForWriteOperations"/>
+ <xs:enumeration value="ErrorClientDisconnected"/>
+ <xs:enumeration value="ErrorClientIntentInvalidStateDefinition"/>
+ <xs:enumeration value="ErrorClientIntentNotFound"/>
+ <xs:enumeration value="ErrorConnectionFailed"/>
+ <xs:enumeration value="ErrorContainsFilterWrongType"/>
+ <xs:enumeration value="ErrorContentConversionFailed"/>
+ <xs:enumeration value="ErrorContentIndexingNotEnabled"/>
+ <xs:enumeration value="ErrorCorruptData"/>
+ <xs:enumeration value="ErrorCreateItemAccessDenied"/>
+ <xs:enumeration value="ErrorCreateManagedFolderPartialCompletion"/>
+ <xs:enumeration value="ErrorCreateSubfolderAccessDenied"/>
+ <xs:enumeration value="ErrorCrossMailboxMoveCopy"/>
+ <xs:enumeration value="ErrorCrossSiteRequest"/>
+ <xs:enumeration value="ErrorDataSizeLimitExceeded"/>
+ <xs:enumeration value="ErrorDataSourceOperation"/>
+ <xs:enumeration value="ErrorDelegateAlreadyExists"/>
+ <xs:enumeration value="ErrorDelegateCannotAddOwner"/>
+ <xs:enumeration value="ErrorDelegateMissingConfiguration"/>
+ <xs:enumeration value="ErrorDelegateNoUser"/>
+ <xs:enumeration value="ErrorDelegateValidationFailed"/>
+ <xs:enumeration value="ErrorDeleteDistinguishedFolder"/>
+ <xs:enumeration value="ErrorDeleteItemsFailed"/>
+ <xs:enumeration value="ErrorDeleteUnifiedMessagingPromptFailed"/>
+ <xs:enumeration value="ErrorDistinguishedUserNotSupported"/>
+ <xs:enumeration value="ErrorDistributionListMemberNotExist"/>
+ <xs:enumeration value="ErrorDuplicateInputFolderNames"/>
+ <xs:enumeration value="ErrorDuplicateUserIdsSpecified"/>
+ <xs:enumeration value="ErrorEmailAddressMismatch"/>
+ <xs:enumeration value="ErrorEventNotFound"/>
+ <xs:enumeration value="ErrorExceededConnectionCount"/>
+ <xs:enumeration value="ErrorExceededSubscriptionCount"/>
+ <xs:enumeration value="ErrorExceededFindCountLimit"/>
+ <xs:enumeration value="ErrorExpiredSubscription"/>
+ <xs:enumeration value="ErrorExtensionNotFound"/>
+ <xs:enumeration value="ErrorFolderCorrupt"/>
+ <xs:enumeration value="ErrorFolderNotFound"/>
+ <xs:enumeration value="ErrorFolderPropertRequestFailed"/>
+ <xs:enumeration value="ErrorFolderSave"/>
+ <xs:enumeration value="ErrorFolderSaveFailed"/>
+ <xs:enumeration value="ErrorFolderSavePropertyError"/>
+ <xs:enumeration value="ErrorFolderExists"/>
+ <xs:enumeration value="ErrorFreeBusyGenerationFailed"/>
+ <xs:enumeration value="ErrorGetServerSecurityDescriptorFailed"/>
+ <xs:enumeration value="ErrorImContactLimitReached"/>
+ <xs:enumeration value="ErrorImGroupDisplayNameAlreadyExists"/>
+ <xs:enumeration value="ErrorImGroupLimitReached"/>
+ <xs:enumeration value="ErrorImpersonateUserDenied"/>
+ <xs:enumeration value="ErrorImpersonationDenied"/>
+ <xs:enumeration value="ErrorImpersonationFailed"/>
+ <xs:enumeration value="ErrorIncorrectSchemaVersion"/>
+ <xs:enumeration value="ErrorIncorrectUpdatePropertyCount"/>
+ <xs:enumeration value="ErrorIndividualMailboxLimitReached"/>
+ <xs:enumeration value="ErrorInsufficientResources"/>
+ <xs:enumeration value="ErrorInternalServerError"/>
+ <xs:enumeration value="ErrorInternalServerTransientError"/>
+ <xs:enumeration value="ErrorInvalidAccessLevel"/>
+ <xs:enumeration value="ErrorInvalidArgument"/>
+ <xs:enumeration value="ErrorInvalidAttachmentId"/>
+ <xs:enumeration value="ErrorInvalidAttachmentSubfilter"/>
+ <xs:enumeration value="ErrorInvalidAttachmentSubfilterTextFilter"/>
+ <xs:enumeration value="ErrorInvalidAuthorizationContext"/>
+ <xs:enumeration value="ErrorInvalidChangeKey"/>
+ <xs:enumeration value="ErrorInvalidClientSecurityContext"/>
+ <xs:enumeration value="ErrorInvalidCompleteDate"/>
+ <xs:enumeration value="ErrorInvalidContactEmailAddress"/>
+ <xs:enumeration value="ErrorInvalidContactEmailIndex"/>
+ <xs:enumeration value="ErrorInvalidCrossForestCredentials"/>
+ <xs:enumeration value="ErrorInvalidDelegatePermission"/>
+ <xs:enumeration value="ErrorInvalidDelegateUserId"/>
+ <xs:enumeration value="ErrorInvalidExcludesRestriction"/>
+ <xs:enumeration value="ErrorInvalidExpressionTypeForSubFilter"/>
+ <xs:enumeration value="ErrorInvalidExtendedProperty"/>
+ <xs:enumeration value="ErrorInvalidExtendedPropertyValue"/>
+ <xs:enumeration value="ErrorInvalidFolderId"/>
+ <xs:enumeration value="ErrorInvalidFolderTypeForOperation"/>
+ <xs:enumeration value="ErrorInvalidFractionalPagingParameters"/>
+ <xs:enumeration value="ErrorInvalidFreeBusyViewType"/>
+ <xs:enumeration value="ErrorInvalidId"/>
+ <xs:enumeration value="ErrorInvalidIdEmpty"/>
+ <xs:enumeration value="ErrorInvalidIdMalformed"/>
+ <xs:enumeration value="ErrorInvalidIdMalformedEwsLegacyIdFormat"/>
+ <xs:enumeration value="ErrorInvalidIdMonikerTooLong"/>
+ <xs:enumeration value="ErrorInvalidIdNotAnItemAttachmentId"/>
+ <xs:enumeration value="ErrorInvalidIdReturnedByResolveNames"/>
+ <xs:enumeration value="ErrorInvalidIdStoreObjectIdTooLong"/>
+ <xs:enumeration value="ErrorInvalidIdTooManyAttachmentLevels"/>
+ <xs:enumeration value="ErrorInvalidIdXml"/>
+ <xs:enumeration value="ErrorInvalidImContactId"/>
+ <xs:enumeration value="ErrorInvalidImDistributionGroupSmtpAddress"/>
+ <xs:enumeration value="ErrorInvalidImGroupId"/>
+ <xs:enumeration value="ErrorInvalidIndexedPagingParameters"/>
+ <xs:enumeration value="ErrorInvalidInternetHeaderChildNodes"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationArchiveItem"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationCreateItemAttachment"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationCreateItem"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationAcceptItem"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationDeclineItem"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationCancelItem"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationExpandDL"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationRemoveItem"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationSendItem"/>
+ <xs:enumeration value="ErrorInvalidItemForOperationTentative"/>
+ <xs:enumeration value="ErrorInvalidLogonType"/>
+ <xs:enumeration value="ErrorInvalidLikeRequest"/>
+ <xs:enumeration value="ErrorInvalidMailbox"/>
+ <xs:enumeration value="ErrorInvalidManagedFolderProperty"/>
+ <xs:enumeration value="ErrorInvalidManagedFolderQuota"/>
+ <xs:enumeration value="ErrorInvalidManagedFolderSize"/>
+ <xs:enumeration value="ErrorInvalidMergedFreeBusyInterval"/>
+ <xs:enumeration value="ErrorInvalidNameForNameResolution"/>
+ <xs:enumeration value="ErrorInvalidOperation"/>
+ <xs:enumeration value="ErrorInvalidNetworkServiceContext"/>
+ <xs:enumeration value="ErrorInvalidOofParameter"/>
+ <xs:enumeration value="ErrorInvalidPagingMaxRows"/>
+ <xs:enumeration value="ErrorInvalidParentFolder"/>
+ <xs:enumeration value="ErrorInvalidPercentCompleteValue"/>
+ <xs:enumeration value="ErrorInvalidPermissionSettings"/>
+ <xs:enumeration value="ErrorInvalidPhoneCallId"/>
+ <xs:enumeration value="ErrorInvalidPhoneNumber"/>
+ <xs:enumeration value="ErrorInvalidUserInfo"/>
+ <xs:enumeration value="ErrorInvalidPropertyAppend"/>
+ <xs:enumeration value="ErrorInvalidPropertyDelete"/>
+ <xs:enumeration value="ErrorInvalidPropertyForExists"/>
+ <xs:enumeration value="ErrorInvalidPropertyForOperation"/>
+ <xs:enumeration value="ErrorInvalidPropertyRequest"/>
+ <xs:enumeration value="ErrorInvalidPropertySet"/>
+ <xs:enumeration value="ErrorInvalidPropertyUpdateSentMessage"/>
+ <xs:enumeration value="ErrorInvalidProxySecurityContext"/>
+ <xs:enumeration value="ErrorInvalidPullSubscriptionId"/>
+ <xs:enumeration value="ErrorInvalidPushSubscriptionUrl"/>
+ <xs:enumeration value="ErrorInvalidRecipients"/>
+ <xs:enumeration value="ErrorInvalidRecipientSubfilter"/>
+ <xs:enumeration value="ErrorInvalidRecipientSubfilterComparison"/>
+ <xs:enumeration value="ErrorInvalidRecipientSubfilterOrder"/>
+ <xs:enumeration value="ErrorInvalidRecipientSubfilterTextFilter"/>
+ <xs:enumeration value="ErrorInvalidReferenceItem"/>
+ <xs:enumeration value="ErrorInvalidRequest"/>
+ <xs:enumeration value="ErrorInvalidRestriction"/>
+ <xs:enumeration value="ErrorInvalidRetentionTagTypeMismatch"/>
+ <xs:enumeration value="ErrorInvalidRetentionTagInvisible"/>
+ <xs:enumeration value="ErrorInvalidRetentionTagInheritance"/>
+ <xs:enumeration value="ErrorInvalidRetentionTagIdGuid"/>
+ <xs:enumeration value="ErrorInvalidRoutingType"/>
+ <xs:enumeration value="ErrorInvalidScheduledOofDuration"/>
+ <xs:enumeration value="ErrorInvalidSchemaVersionForMailboxVersion"/>
+ <xs:enumeration value="ErrorInvalidSecurityDescriptor"/>
+ <xs:enumeration value="ErrorInvalidSendItemSaveSettings"/>
+ <xs:enumeration value="ErrorInvalidSerializedAccessToken"/>
+ <xs:enumeration value="ErrorInvalidServerVersion"/>
+ <xs:enumeration value="ErrorInvalidSid"/>
+ <xs:enumeration value="ErrorInvalidSIPUri"/>
+ <xs:enumeration value="ErrorInvalidSmtpAddress"/>
+ <xs:enumeration value="ErrorInvalidSubfilterType"/>
+ <xs:enumeration value="ErrorInvalidSubfilterTypeNotAttendeeType"/>
+ <xs:enumeration value="ErrorInvalidSubfilterTypeNotRecipientType"/>
+ <xs:enumeration value="ErrorInvalidSubscription"/>
+ <xs:enumeration value="ErrorInvalidSubscriptionRequest"/>
+ <xs:enumeration value="ErrorInvalidSyncStateData"/>
+ <xs:enumeration value="ErrorInvalidTimeInterval"/>
+ <xs:enumeration value="ErrorInvalidUserOofSettings"/>
+ <xs:enumeration value="ErrorInvalidUserPrincipalName"/>
+ <xs:enumeration value="ErrorInvalidUserSid"/>
+ <xs:enumeration value="ErrorInvalidUserSidMissingUPN"/>
+ <xs:enumeration value="ErrorInvalidValueForProperty"/>
+ <xs:enumeration value="ErrorInvalidWatermark"/>
+ <xs:enumeration value="ErrorIPGatewayNotFound"/>
+ <xs:enumeration value="ErrorIrresolvableConflict"/>
+ <xs:enumeration value="ErrorItemCorrupt"/>
+ <xs:enumeration value="ErrorItemNotFound"/>
+ <xs:enumeration value="ErrorItemPropertyRequestFailed"/>
+ <xs:enumeration value="ErrorItemSave"/>
+ <xs:enumeration value="ErrorItemSavePropertyError"/>
+ <xs:enumeration value="ErrorLegacyMailboxFreeBusyViewTypeNotMerged"/>
+ <xs:enumeration value="ErrorLocalServerObjectNotFound"/>
+ <xs:enumeration value="ErrorLogonAsNetworkServiceFailed"/>
+ <xs:enumeration value="ErrorMailboxConfiguration"/>
+ <xs:enumeration value="ErrorMailboxDataArrayEmpty"/>
+ <xs:enumeration value="ErrorMailboxDataArrayTooBig"/>
+ <xs:enumeration value="ErrorMailboxHoldNotFound"/>
+ <xs:enumeration value="ErrorMailboxLogonFailed"/>
+ <xs:enumeration value="ErrorMailboxMoveInProgress"/>
+ <xs:enumeration value="ErrorMailboxStoreUnavailable"/>
+ <xs:enumeration value="ErrorMailRecipientNotFound"/>
+ <xs:enumeration value="ErrorMailTipsDisabled"/>
+ <xs:enumeration value="ErrorManagedFolderAlreadyExists"/>
+ <xs:enumeration value="ErrorManagedFolderNotFound"/>
+ <xs:enumeration value="ErrorManagedFoldersRootFailure"/>
+ <xs:enumeration value="ErrorMeetingSuggestionGenerationFailed"/>
+ <xs:enumeration value="ErrorMessageDispositionRequired"/>
+ <xs:enumeration value="ErrorMessageSizeExceeded"/>
+ <xs:enumeration value="ErrorMimeContentConversionFailed"/>
+ <xs:enumeration value="ErrorMimeContentInvalid"/>
+ <xs:enumeration value="ErrorMimeContentInvalidBase64String"/>
+ <xs:enumeration value="ErrorMissingArgument"/>
+ <xs:enumeration value="ErrorMissingEmailAddress"/>
+ <xs:enumeration value="ErrorMissingEmailAddressForManagedFolder"/>
+ <xs:enumeration value="ErrorMissingInformationEmailAddress"/>
+ <xs:enumeration value="ErrorMissingInformationReferenceItemId"/>
+ <xs:enumeration value="ErrorMissingItemForCreateItemAttachment"/>
+ <xs:enumeration value="ErrorMissingManagedFolderId"/>
+ <xs:enumeration value="ErrorMissingRecipients"/>
+ <xs:enumeration value="ErrorMissingUserIdInformation"/>
+ <xs:enumeration value="ErrorMoreThanOneAccessModeSpecified"/>
+ <xs:enumeration value="ErrorMoveCopyFailed"/>
+ <xs:enumeration value="ErrorMoveDistinguishedFolder"/>
+ <xs:enumeration value="ErrorMultiLegacyMailboxAccess"/>
+ <xs:enumeration value="ErrorNameResolutionMultipleResults"/>
+ <xs:enumeration value="ErrorNameResolutionNoMailbox"/>
+ <xs:enumeration value="ErrorNameResolutionNoResults"/>
+ <xs:enumeration value="ErrorNoApplicableProxyCASServersAvailable"/>
+ <xs:enumeration value="ErrorNoCalendar"/>
+ <xs:enumeration value="ErrorNoDestinationCASDueToKerberosRequirements"/>
+ <xs:enumeration value="ErrorNoDestinationCASDueToSSLRequirements"/>
+ <xs:enumeration value="ErrorNoDestinationCASDueToVersionMismatch"/>
+ <xs:enumeration value="ErrorNoFolderClassOverride"/>
+ <xs:enumeration value="ErrorNoFreeBusyAccess"/>
+ <xs:enumeration value="ErrorNonExistentMailbox"/>
+ <xs:enumeration value="ErrorNonPrimarySmtpAddress"/>
+ <xs:enumeration value="ErrorNoPropertyTagForCustomProperties"/>
+ <xs:enumeration value="ErrorNoPublicFolderReplicaAvailable"/>
+ <xs:enumeration value="ErrorNoPublicFolderServerAvailable"/>
+ <xs:enumeration value="ErrorNoRespondingCASInDestinationSite"/>
+ <xs:enumeration value="ErrorNotDelegate"/>
+ <xs:enumeration value="ErrorNotEnoughMemory"/>
+ <xs:enumeration value="ErrorObjectTypeChanged"/>
+ <xs:enumeration value="ErrorOccurrenceCrossingBoundary"/>
+ <xs:enumeration value="ErrorOccurrenceTimeSpanTooBig" />
+ <xs:enumeration value="ErrorOperationNotAllowedWithPublicFolderRoot" />
+ <xs:enumeration value="ErrorParentFolderIdRequired"/>
+ <xs:enumeration value="ErrorParentFolderNotFound"/>
+ <xs:enumeration value="ErrorPasswordChangeRequired"/>
+ <xs:enumeration value="ErrorPasswordExpired"/>
+ <xs:enumeration value="ErrorPhoneNumberNotDialable"/>
+ <xs:enumeration value="ErrorPropertyUpdate"/>
+ <xs:enumeration value="ErrorPromptPublishingOperationFailed"/>
+ <xs:enumeration value="ErrorPropertyValidationFailure"/>
+ <xs:enumeration value="ErrorProxiedSubscriptionCallFailure"/>
+ <xs:enumeration value="ErrorProxyCallFailed"/>
+ <xs:enumeration value="ErrorProxyGroupSidLimitExceeded"/>
+ <xs:enumeration value="ErrorProxyRequestNotAllowed"/>
+ <xs:enumeration value="ErrorProxyRequestProcessingFailed"/>
+ <xs:enumeration value="ErrorProxyServiceDiscoveryFailed"/>
+ <xs:enumeration value="ErrorProxyTokenExpired"/>
+ <xs:enumeration value="ErrorPublicFolderMailboxDiscoveryFailed"/>
+ <xs:enumeration value="ErrorPublicFolderOperationFailed"/>
+ <xs:enumeration value="ErrorPublicFolderRequestProcessingFailed"/>
+ <xs:enumeration value="ErrorPublicFolderServerNotFound"/>
+ <xs:enumeration value="ErrorPublicFolderSyncException"/>
+ <xs:enumeration value="ErrorQueryFilterTooLong"/>
+ <xs:enumeration value="ErrorQuotaExceeded"/>
+ <xs:enumeration value="ErrorReadEventsFailed"/>
+ <xs:enumeration value="ErrorReadReceiptNotPending"/>
+ <xs:enumeration value="ErrorRecurrenceEndDateTooBig"/>
+ <xs:enumeration value="ErrorRecurrenceHasNoOccurrence"/>
+ <xs:enumeration value="ErrorRemoveDelegatesFailed"/>
+ <xs:enumeration value="ErrorRequestAborted"/>
+ <xs:enumeration value="ErrorRequestStreamTooBig"/>
+ <xs:enumeration value="ErrorRequiredPropertyMissing"/>
+ <xs:enumeration value="ErrorResolveNamesInvalidFolderType"/>
+ <xs:enumeration value="ErrorResolveNamesOnlyOneContactsFolderAllowed"/>
+ <xs:enumeration value="ErrorResponseSchemaValidation"/>
+ <xs:enumeration value="ErrorRestrictionTooLong"/>
+ <xs:enumeration value="ErrorRestrictionTooComplex"/>
+ <xs:enumeration value="ErrorResultSetTooBig"/>
+ <xs:enumeration value="ErrorInvalidExchangeImpersonationHeaderData"/>
+ <xs:enumeration value="ErrorSavedItemFolderNotFound"/>
+ <xs:enumeration value="ErrorSchemaValidation"/>
+ <xs:enumeration value="ErrorSearchFolderNotInitialized"/>
+ <xs:enumeration value="ErrorSendAsDenied"/>
+ <xs:enumeration value="ErrorSendMeetingCancellationsRequired"/>
+ <xs:enumeration value="ErrorSendMeetingInvitationsOrCancellationsRequired"/>
+ <xs:enumeration value="ErrorSendMeetingInvitationsRequired"/>
+ <xs:enumeration value="ErrorSentMeetingRequestUpdate"/>
+ <xs:enumeration value="ErrorSentTaskRequestUpdate"/>
+ <xs:enumeration value="ErrorServerBusy"/>
+ <xs:enumeration value="ErrorServiceDiscoveryFailed"/>
+ <xs:enumeration value="ErrorStaleObject"/>
+ <xs:enumeration value="ErrorSubmissionQuotaExceeded"/>
+ <xs:enumeration value="ErrorSubscriptionAccessDenied"/>
+ <xs:enumeration value="ErrorSubscriptionDelegateAccessNotSupported"/>
+ <xs:enumeration value="ErrorSubscriptionNotFound"/>
+ <xs:enumeration value="ErrorSubscriptionUnsubscribed"/>
+ <xs:enumeration value="ErrorSyncFolderNotFound"/>
+ <xs:enumeration value="ErrorTeamMailboxNotFound"/>
+ <xs:enumeration value="ErrorTeamMailboxNotLinkedToSharePoint"/>
+ <xs:enumeration value="ErrorTeamMailboxUrlValidationFailed"/>
+ <xs:enumeration value="ErrorTeamMailboxNotAuthorizedOwner"/>
+ <xs:enumeration value="ErrorTeamMailboxActiveToPendingDelete"/>
+ <xs:enumeration value="ErrorTeamMailboxFailedSendingNotifications"/>
+ <xs:enumeration value="ErrorTeamMailboxErrorUnknown"/>
+ <xs:enumeration value="ErrorTimeIntervalTooBig"/>
+ <xs:enumeration value="ErrorTimeoutExpired"/>
+ <xs:enumeration value="ErrorTimeZone"/>
+ <xs:enumeration value="ErrorToFolderNotFound"/>
+ <xs:enumeration value="ErrorTokenSerializationDenied"/>
+ <xs:enumeration value="ErrorTooManyObjectsOpened"/>
+ <xs:enumeration value="ErrorUpdatePropertyMismatch"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxAADCreationFailed"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxAADDeleteFailed"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxNamingPolicy"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxDeleteFailed"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxNotFound"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxUpdateDelayed"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxUpdatedPartialProperties"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxUpdateFailed"/>
+ <xs:enumeration value="ErrorUnifiedGroupMailboxProvisionFailed"/>
+ <xs:enumeration value="ErrorUnifiedMessagingDialPlanNotFound"/>
+ <xs:enumeration value="ErrorUnifiedMessagingReportDataNotFound"/>
+ <xs:enumeration value="ErrorUnifiedMessagingPromptNotFound"/>
+ <xs:enumeration value="ErrorUnifiedMessagingRequestFailed"/>
+ <xs:enumeration value="ErrorUnifiedMessagingServerNotFound"/>
+ <xs:enumeration value="ErrorUnableToGetUserOofSettings"/>
+ <xs:enumeration value="ErrorUnableToRemoveImContactFromGroup"/>
+ <xs:enumeration value="ErrorUnsupportedSubFilter"/>
+ <xs:enumeration value="ErrorUnsupportedCulture"/>
+ <xs:enumeration value="ErrorUnsupportedMapiPropertyType"/>
+ <xs:enumeration value="ErrorUnsupportedMimeConversion"/>
+ <xs:enumeration value="ErrorUnsupportedPathForQuery"/>
+ <xs:enumeration value="ErrorUnsupportedPathForSortGroup"/>
+ <xs:enumeration value="ErrorUnsupportedPropertyDefinition"/>
+ <xs:enumeration value="ErrorUnsupportedQueryFilter"/>
+ <xs:enumeration value="ErrorUnsupportedRecurrence"/>
+ <xs:enumeration value="ErrorUnsupportedTypeForConversion"/>
+ <xs:enumeration value="ErrorUpdateDelegatesFailed"/>
+ <xs:enumeration value="ErrorUserNotUnifiedMessagingEnabled"/>
+ <xs:enumeration value="ErrorVoiceMailNotImplemented"/>
+ <xs:enumeration value="ErrorValueOutOfRange"/>
+ <xs:enumeration value="ErrorVirusDetected"/>
+ <xs:enumeration value="ErrorVirusMessageDeleted"/>
+ <xs:enumeration value="ErrorWebRequestInInvalidState"/>
+ <xs:enumeration value="ErrorWin32InteropError"/>
+ <xs:enumeration value="ErrorWorkingHoursSaveFailed"/>
+ <xs:enumeration value="ErrorWorkingHoursXmlMalformed"/>
+ <xs:enumeration value="ErrorWrongServerVersion"/>
+ <xs:enumeration value="ErrorWrongServerVersionDelegate"/>
+ <xs:enumeration value="ErrorMissingInformationSharingFolderId"/>
+ <xs:enumeration value="ErrorDuplicateSOAPHeader" />
+ <xs:enumeration value="ErrorSharingSynchronizationFailed" />
+ <xs:enumeration value="ErrorSharingNoExternalEwsAvailable" />
+ <xs:enumeration value="ErrorFreeBusyDLLimitReached"/>
+ <xs:enumeration value="ErrorInvalidGetSharingFolderRequest" />
+ <xs:enumeration value="ErrorNotAllowedExternalSharingByPolicy" />
+ <xs:enumeration value="ErrorUserNotAllowedByPolicy" />
+ <xs:enumeration value="ErrorPermissionNotAllowedByPolicy" />
+ <xs:enumeration value="ErrorOrganizationNotFederated" />
+ <xs:enumeration value="ErrorMailboxFailover" />
+ <xs:enumeration value="ErrorInvalidExternalSharingInitiator" />
+ <xs:enumeration value="ErrorMessageTrackingPermanentError" />
+ <xs:enumeration value="ErrorMessageTrackingTransientError" />
+ <xs:enumeration value="ErrorMessageTrackingNoSuchDomain" />
+ <xs:enumeration value="ErrorUserWithoutFederatedProxyAddress" />
+ <xs:enumeration value="ErrorInvalidOrganizationRelationshipForFreeBusy" />
+ <xs:enumeration value="ErrorInvalidFederatedOrganizationId" />
+ <xs:enumeration value="ErrorInvalidExternalSharingSubscriber" />
+ <xs:enumeration value="ErrorInvalidSharingData" />
+ <xs:enumeration value="ErrorInvalidSharingMessage" />
+ <xs:enumeration value="ErrorNotSupportedSharingMessage" />
+ <xs:enumeration value="ErrorApplyConversationActionFailed" />
+ <xs:enumeration value="ErrorInboxRulesValidationError" />
+ <xs:enumeration value="ErrorOutlookRuleBlobExists" />
+ <xs:enumeration value="ErrorRulesOverQuota" />
+ <xs:enumeration value="ErrorNewEventStreamConnectionOpened" />
+ <xs:enumeration value="ErrorMissedNotificationEvents" />
+ <xs:enumeration value="ErrorDuplicateLegacyDistinguishedName" />
+ <xs:enumeration value="ErrorInvalidClientAccessTokenRequest" />
+ <xs:enumeration value="ErrorNoSpeechDetected" />
+ <xs:enumeration value="ErrorUMServerUnavailable" />
+ <xs:enumeration value="ErrorRecipientNotFound" />
+ <xs:enumeration value="ErrorRecognizerNotInstalled" />
+ <xs:enumeration value="ErrorSpeechGrammarError" />
+ <xs:enumeration value="ErrorInvalidManagementRoleHeader" />
+ <xs:enumeration value="ErrorLocationServicesDisabled"/>
+ <xs:enumeration value="ErrorLocationServicesRequestTimedOut"/>
+ <xs:enumeration value="ErrorLocationServicesRequestFailed"/>
+ <xs:enumeration value="ErrorLocationServicesInvalidRequest"/>
+ <xs:enumeration value="ErrorWeatherServiceDisabled"/>
+ <xs:enumeration value="ErrorMailboxScopeNotAllowedWithoutQueryString" />
+ <xs:enumeration value="ErrorArchiveMailboxSearchFailed" />
+ <xs:enumeration value="ErrorGetRemoteArchiveFolderFailed" />
+ <xs:enumeration value="ErrorFindRemoteArchiveFolderFailed" />
+ <xs:enumeration value="ErrorGetRemoteArchiveItemFailed" />
+ <xs:enumeration value="ErrorExportRemoteArchiveItemsFailed" />
+ <xs:enumeration value="ErrorInvalidPhotoSize" />
+ <xs:enumeration value="ErrorSearchQueryHasTooManyKeywords"/>
+ <xs:enumeration value="ErrorSearchTooManyMailboxes"/>
+ <xs:enumeration value="ErrorInvalidRetentionTagNone"/>
+ <xs:enumeration value="ErrorDiscoverySearchesDisabled"/>
+ <xs:enumeration value="ErrorCalendarSeekToConditionNotSupported"/>
+ <xs:enumeration value="ErrorCalendarIsGroupMailboxForAccept"/>
+ <xs:enumeration value="ErrorCalendarIsGroupMailboxForDecline"/>
+ <xs:enumeration value="ErrorCalendarIsGroupMailboxForTentative"/>
+ <xs:enumeration value="ErrorCalendarIsGroupMailboxForSuppressReadReceipt"/>
+ <xs:enumeration value="ErrorOrganizationAccessBlocked"/>
+ <xs:enumeration value="ErrorInvalidLicense"/>
+ <xs:enumeration value="ErrorMessagePerFolderCountReceiveQuotaExceeded"/>
+ <xs:enumeration value="ErrorInvalidBulkActionType"/>
+ <xs:enumeration value="ErrorInvalidKeepNCount"/>
+ <xs:enumeration value="ErrorInvalidKeepNType"/>
+ <xs:enumeration value="ErrorNoOAuthServerAvailableForRequest"/>
+ <xs:enumeration value="ErrorInstantSearchSessionExpired"/>
+ <xs:enumeration value="ErrorInstantSearchTimeout"/>
+ <xs:enumeration value="ErrorInstantSearchFailed"/>
+ <xs:enumeration value="ErrorUnsupportedUserForExecuteSearch"/>
+ <xs:enumeration value="ErrorDuplicateExtendedKeywordDefinition"/>
+ <xs:enumeration value="ErrorMissingExchangePrincipal"/>
+ <xs:enumeration value="ErrorUnexpectedUnifiedGroupsCount"/>
+ <xs:enumeration value="ErrorParsingXMLResponse"/>
+ <xs:enumeration value="ErrorInvalidFederationOrganizationIdentifier"/>
+ <xs:enumeration value="ErrorInvalidSweepRule"/>
+ <xs:enumeration value="ErrorInvalidSweepRuleOperationType"/>
+ <xs:enumeration value="ErrorTargetDomainNotSupported"/>
+ <xs:enumeration value="ErrorInvalidInternetWebProxyOnLocalServer"/>
+ <xs:enumeration value="ErrorNoSenderRestrictionsSettingsFoundInRequest"/>
+ <xs:enumeration value="ErrorDuplicateSenderRestrictionsInputFound"/>
+ <xs:enumeration value="ErrorSenderRestrictionsUpdateFailed"/>
+ <xs:enumeration value="ErrorMessageSubmissionBlocked"/>
+ <xs:enumeration value="ErrorExceededMessageLimit"/>
+ <xs:enumeration value="ErrorExceededMaxRecipientLimitBlock"/>
+ <xs:enumeration value="ErrorAccountSuspend"/>
+ <xs:enumeration value="ErrorExceededMaxRecipientLimit"/>
+ <xs:enumeration value="ErrorMessageBlocked"/>
+ <xs:enumeration value="ErrorAccountSuspendShowTierUpgrade"/>
+ <xs:enumeration value="ErrorExceededMessageLimitShowTierUpgrade"/>
+ <xs:enumeration value="ErrorExceededMaxRecipientLimitShowTierUpgrade"/>
+ <xs:enumeration value="ErrorInvalidLongitude"/>
+ <xs:enumeration value="ErrorInvalidLatitude"/>
+ <xs:enumeration value="ErrorProxySoapException"/>
+ <xs:enumeration value="ErrorUnifiedGroupAlreadyExists"/>
+ <xs:enumeration value="ErrorUnifiedGroupAadAuthorizationRequestDenied"/>
+ <xs:enumeration value="ErrorUnifiedGroupCreationDisabled"/>
+ <xs:enumeration value="ErrorMarketPlaceExtensionAlreadyInstalledForOrg"/>
+ <xs:enumeration value="ErrorExtensionAlreadyInstalledForOrg"/>
+ <xs:enumeration value="ErrorNewerExtensionAlreadyInstalled"/>
+ <xs:enumeration value="ErrorNewerMarketPlaceExtensionAlreadyInstalled"/>
+ <xs:enumeration value="ErrorInvalidExtensionId"/>
+ <xs:enumeration value="ErrorCannotUninstallProvidedExtensions"/>
+ <xs:enumeration value="ErrorNoRbacPermissionToInstallMarketPlaceExtensions"/>
+ <xs:enumeration value="ErrorNoRbacPermissionToInstallReadWriteMailboxExtensions"/>
+ <xs:enumeration value="ErrorInvalidReportMessageActionType"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ResponseMessageType">
+ <xs:sequence minOccurs="0">
+ <xs:element name="MessageText" type="xs:string" minOccurs="0"/>
+ <xs:element name="ResponseCode" type="m:ResponseCodeType" minOccurs="0"/>
+ <xs:element name="DescriptiveLinkKey" type="xs:int" minOccurs="0"/>
+ <xs:element name="MessageXml" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="ResponseClass" type="t:ResponseClassType" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="ArrayOfResponseMessagesType">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="CreateItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
+ <xs:element name="DeleteItemResponseMessage" type="m:DeleteItemResponseMessageType"/>
+ <xs:element name="GetItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
+ <xs:element name="UpdateItemResponseMessage" type="m:UpdateItemResponseMessageType"/>
+ <xs:element name="UpdateItemInRecoverableItemsResponseMessage" type="m:UpdateItemInRecoverableItemsResponseMessageType"/>
+ <xs:element name="SendItemResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="DeleteFolderResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="EmptyFolderResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="CreateFolderResponseMessage" type="m:FolderInfoResponseMessageType"/>
+ <xs:element name="GetFolderResponseMessage" type="m:FolderInfoResponseMessageType"/>
+ <xs:element name="FindFolderResponseMessage" type="m:FindFolderResponseMessageType"/>
+ <xs:element name="UpdateFolderResponseMessage" type="m:FolderInfoResponseMessageType"/>
+ <xs:element name="MoveFolderResponseMessage" type="m:FolderInfoResponseMessageType"/>
+ <xs:element name="CopyFolderResponseMessage" type="m:FolderInfoResponseMessageType"/>
+ <xs:element name="CreateFolderPathResponseMessage" type="m:FolderInfoResponseMessageType"/>
+ <xs:element name="CreateAttachmentResponseMessage" type="m:AttachmentInfoResponseMessageType"/>
+ <xs:element name="DeleteAttachmentResponseMessage" type="m:DeleteAttachmentResponseMessageType"/>
+ <xs:element name="GetAttachmentResponseMessage" type="m:AttachmentInfoResponseMessageType"/>
+ <xs:element name="UploadItemsResponseMessage" type="m:UploadItemsResponseMessageType"/>
+ <xs:element name="ExportItemsResponseMessage" type="m:ExportItemsResponseMessageType"/>
+ <xs:element name="MarkAllItemsAsReadResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="GetClientAccessTokenResponseMessage" type="m:GetClientAccessTokenResponseMessageType"/>
+ <xs:element name="GetAppManifestsResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="SetClientExtensionResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="GetOMEConfigurationResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="SetOMEConfigurationResponseMessage" type="m:ResponseMessageType"/>
+ <!-- Generic response to enumerating the items below a folder -->
+ <xs:element name="FindItemResponseMessage" type="m:FindItemResponseMessageType"/>
+ <xs:element name="MoveItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
+ <xs:element name="ArchiveItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
+ <xs:element name="CopyItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
+ <!-- ANR responses -->
+ <xs:element name="ResolveNamesResponseMessage" type="m:ResolveNamesResponseMessageType"/>
+ <xs:element name="ExpandDLResponseMessage" type="m:ExpandDLResponseMessageType"/>
+ <!-- GetServerTimeZones response -->
+ <xs:element name="GetServerTimeZonesResponseMessage" type="m:GetServerTimeZonesResponseMessageType"/>
+ <!-- Notification responses -->
+ <xs:element name="GetEventsResponseMessage" type="m:GetEventsResponseMessageType"/>
+ <xs:element name="GetStreamingEventsResponseMessage" type="m:GetStreamingEventsResponseMessageType"/>
+ <xs:element name="SubscribeResponseMessage" type="m:SubscribeResponseMessageType"/>
+ <xs:element name="UnsubscribeResponseMessage" type="m:ResponseMessageType"/>
+ <!-- Send Notification response -->
+ <xs:element name="SendNotificationResponseMessage" type="m:SendNotificationResponseMessageType" />
+ <!-- Sync responses -->
+ <xs:element name="SyncFolderHierarchyResponseMessage" type="m:SyncFolderHierarchyResponseMessageType"/>
+ <xs:element name="SyncFolderItemsResponseMessage" type="m:SyncFolderItemsResponseMessageType"/>
+ <!-- Managed Folder responses -->
+ <xs:element name="CreateManagedFolderResponseMessage" type="m:FolderInfoResponseMessageType"/>
+ <!-- ConvertId response-->
+ <xs:element name="ConvertIdResponseMessage" type="m:ConvertIdResponseMessageType"/>
+ <!-- Sharing responses-->
+ <xs:element name="GetSharingMetadataResponseMessage" type="m:GetSharingMetadataResponseMessageType"/>
+ <xs:element name="RefreshSharingFolderResponseMessage" type="m:RefreshSharingFolderResponseMessageType"/>
+ <xs:element name="GetSharingFolderResponseMessage" type="m:GetSharingFolderResponseMessageType"/>
+ <!-- UserConfiguration responses-->
+ <xs:element name="CreateUserConfigurationResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="DeleteUserConfigurationResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="GetUserConfigurationResponseMessage" type="m:GetUserConfigurationResponseMessageType"/>
+ <xs:element name="GetSpecificUserConfigurationResponseMessage" type="m:GetSpecificUserConfigurationResponseMessageType"/>
+ <xs:element name="UpdateUserConfigurationResponseMessage" type="m:ResponseMessageType"/>
+ <xs:element name="GetRoomListsResponse" type="m:GetRoomListsResponseMessageType"/>
+ <xs:element name="GetRoomsResponse" type="m:GetRoomsResponseMessageType"/>
+ <xs:element name="GetRemindersResponse" type="m:GetRemindersResponseMessageType"/>
+ <xs:element name="PerformReminderActionResponse" type="m:PerformReminderActionResponseMessageType"/>
+ <!-- ApplyConversation response-->
+ <xs:element name="ApplyConversationActionResponseMessage" type="m:ApplyConversationActionResponseMessageType"/>
+ <!-- FindMailboxStatisticsByKeywords response-->
+ <xs:element name="FindMailboxStatisticsByKeywordsResponseMessage" type="m:FindMailboxStatisticsByKeywordsResponseMessageType"/>
+ <!-- GetSearchableMailboxes response -->
+ <xs:element name="GetSearchableMailboxesResponseMessage" type="m:GetSearchableMailboxesResponseMessageType"/>
+ <!-- SearchMailboxes response -->
+ <xs:element name="SearchMailboxesResponseMessage" type="m:SearchMailboxesResponseMessageType"/>
+ <!-- GetDiscoverySearchConfiguration response -->
+ <xs:element name="GetDiscoverySearchConfigurationResponseMessage" type="m:GetDiscoverySearchConfigurationResponseMessageType"/>
+ <!-- GetHoldOnMailboxes response -->
+ <xs:element name="GetHoldOnMailboxesResponseMessage" type="m:GetHoldOnMailboxesResponseMessageType"/>
+ <!-- SetHoldOnMailboxes response -->
+ <xs:element name="SetHoldOnMailboxesResponseMessage" type="m:SetHoldOnMailboxesResponseMessageType"/>
+ <!-- GetNonIndexableItemStatistics response -->
+ <xs:element name="GetNonIndexableItemStatisticsResponseMessage" type="m:GetNonIndexableItemStatisticsResponseMessageType"/>
+ <!-- GetNonIndexableItemDetails response -->
+ <xs:element name="GetNonIndexableItemDetailsResponseMessage" type="m:GetNonIndexableItemDetailsResponseMessageType"/>
+ <!-- FindPeople response -->
+ <xs:element name="FindPeopleResponseMessage" type="m:FindPeopleResponseMessageType"/>
+ <!-- FindTags response -->
+ <xs:element name="FindTagsResponseMessage" type="m:FindTagsResponseMessageType"/>
+ <!-- AddTag response -->
+ <xs:element name="AddTagResponseMessage" type="m:AddTagResponseMessageType"/>
+ <!-- HideTag response -->
+ <xs:element name="HideTagResponseMessage" type="m:HideTagResponseMessageType"/>
+ <!-- GetPasswordExpirationDate response -->
+ <xs:element name="GetPasswordExpirationDateResponse" type="m:GetPasswordExpirationDateResponseMessageType"/>
+ <!-- GetPersona response -->
+ <xs:element name="GetPersonaResponseMessage" type="m:GetPersonaResponseMessageType"/>
+ <!-- GetConversationItems response -->
+ <xs:element name="GetConversationItemsResponseMessage" type="m:GetConversationItemsResponseMessageType"/>
+ <!-- GetUserRetentionPolicyTags response -->
+ <xs:element name="GetUserRetentionPolicyTagsResponseMessage" type="m:GetUserRetentionPolicyTagsResponseMessageType"/>
+ <!-- GetUserPhoto response -->
+ <xs:element name="GetUserPhotoResponseMessage" type="m:GetUserPhotoResponseMessageType"/>
+ <!-- MarkAsJunk response-->
+ <xs:element name="MarkAsJunkResponseMessage" type="m:MarkAsJunkResponseMessageType" />
+ <!-- ReportMessage response-->
+ <xs:element name="ReportMessageResponseMessage" type="m:ReportMessageResponseMessageType" />
+ <!-- PostModernGroupItem response-->
+ <xs:element name="PostModernGroupItemResponseMessage" type="m:ItemInfoResponseMessageType"/>
+ <!-- GetLastPrivateCatalogUpdate response-->
+ <xs:element name="GetLastPrivateCatalogUpdateResponseMessage" type="m:ResponseMessageType"/>
+ <!-- GetPrivateCatalogAddIns response -->
+ <xs:element name="GetPrivateCatalogAddInsResponseMessage" type="m:ResponseMessageType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- Base types for all messages. -->
+ <xs:complexType name="BaseResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ResponseMessages" type="m:ArrayOfResponseMessagesType"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="BaseRequestType" abstract="true"/>
+ <!-- Folder Service messages. -->
+ <xs:complexType name="GetFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="FolderShape" type="t:FolderResponseShapeType"/>
+ <xs:element name="FolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetFolder" type="m:GetFolderType"/>
+
+ <!-- Upload Items -->
+ <!-- request -->
+ <xs:complexType name="UploadItemsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Items" type="t:NonEmptyArrayOfUploadItemsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UploadItems" type="m:UploadItemsType"/>
+
+ <!-- upload Items response message -->
+ <xs:complexType name="UploadItemsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- upload items response -->
+ <xs:complexType name="UploadItemsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UploadItemsResponse" type="m:UploadItemsResponseType"/>
+
+ <!-- ExportItems -->
+ <xs:complexType name="ExportItemsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfItemIdsType" minOccurs ="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ExportItems" type="m:ExportItemsType"/>
+
+ <!-- ExportItems response message -->
+ <xs:complexType name="ExportItemsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs ="0" maxOccurs ="1"/>
+ <xs:element name="Data" type="xs:base64Binary" minOccurs="0" maxOccurs ="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- ExportItems response type -->
+ <xs:complexType name="ExportItemsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ExportItemsResponse" type="m:ExportItemsResponseType"/>
+
+
+ <!-- Creating a folder. -->
+ <xs:complexType name="CreateFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ParentFolderId" type="t:TargetFolderIdType"/>
+ <xs:element name="Folders" type="t:NonEmptyArrayOfFoldersType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateFolder" type="m:CreateFolderType"/>
+ <!-- Enumerate folders beneath the elements of a list of folders (Reading, 1) -->
+ <xs:complexType name="FindFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="FolderShape" type="t:FolderResponseShapeType"/>
+ <xs:choice maxOccurs="1" minOccurs="0">
+ <xs:element name="IndexedPageFolderView" type="t:IndexedPageViewType"/>
+ <xs:element name="FractionalPageFolderView" type="t:FractionalPageViewType"/>
+ </xs:choice>
+ <xs:element name="Restriction" type="t:RestrictionType" minOccurs="0"/>
+ <xs:element name="ParentFolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType"/>
+ </xs:sequence>
+ <xs:attribute name="Traversal" type="t:FolderQueryTraversalType" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindFolder" type="m:FindFolderType"/>
+ <!-- Generic response to reading a folder's properties. -->
+ <xs:complexType name="FolderInfoResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Folders" type="t:ArrayOfFoldersType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- FindFolder response type-->
+ <xs:complexType name="FindFolderResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="RootFolder" type="t:FindFolderParentType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="FindFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindFolderResponse" type="m:FindFolderResponseType"/>
+ <!-- Deleting a folder. -->
+ <xs:complexType name="DeleteFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="FolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType"/>
+ </xs:sequence>
+ <xs:attribute name="DeleteType" type="t:DisposalType" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteFolder" type="m:DeleteFolderType"/>
+ <xs:complexType name="DeleteFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteFolderResponse" type="m:DeleteFolderResponseType"/>
+ <!-- Emptying a folder. -->
+ <xs:complexType name="EmptyFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="FolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType"/>
+ </xs:sequence>
+ <xs:attribute name="DeleteType" type="t:DisposalType" use="required"/>
+ <xs:attribute name="DeleteSubFolders" type="xs:boolean" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="EmptyFolder" type="m:EmptyFolderType"/>
+ <xs:complexType name="EmptyFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="EmptyFolderResponse" type="m:EmptyFolderResponseType"/>
+ <!-- Base for Move/Copy folders -->
+ <xs:complexType name="BaseMoveCopyFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ToFolderId" type="t:TargetFolderIdType"/>
+ <xs:element name="FolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- Move folders -->
+ <xs:complexType name="MoveFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseMoveCopyFolderType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- Copy folders -->
+ <xs:complexType name="CopyFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseMoveCopyFolderType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="MoveFolder" type="m:MoveFolderType"/>
+ <xs:element name="CopyFolder" type="m:CopyFolderType"/>
+ <xs:complexType name="UpdateFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="FolderChanges" type="t:NonEmptyArrayOfFolderChangesType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UpdateFolder" type="m:UpdateFolderType"/>
+ <xs:complexType name="CreateFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateFolderResponse" type="m:CreateFolderResponseType"/>
+ <xs:complexType name="GetFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetFolderResponse" type="m:GetFolderResponseType"/>
+ <xs:complexType name="UpdateFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UpdateFolderResponse" type="m:UpdateFolderResponseType"/>
+ <xs:complexType name="MoveFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="CopyFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="MoveFolderResponse" type="m:MoveFolderResponseType"/>
+ <xs:element name="CopyFolderResponse" type="m:CopyFolderResponseType"/>
+
+ <xs:complexType name="CreateFolderPathType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ParentFolderId" type="t:TargetFolderIdType"/>
+ <xs:element name="RelativeFolderPath" type="t:NonEmptyArrayOfFoldersType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateFolderPath" type="m:CreateFolderPathType"/>
+ <xs:complexType name="CreateFolderPathResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateFolderPathResponse" type="m:CreateFolderPathResponseType"/>
+ <!-- Reading an item. -->
+
+ <xs:complexType name="GetItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemShape" type="t:ItemResponseShapeType"/>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetItem" type="m:GetItemType"/>
+
+ <xs:complexType name="CreateItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SavedItemFolderId" type="t:TargetFolderIdType" minOccurs="0"/>
+ <xs:element name="Items" type="t:NonEmptyArrayOfAllItemsType"/>
+ </xs:sequence>
+ <xs:attribute name="MessageDisposition" type="t:MessageDispositionType" use="optional"/>
+ <xs:attribute name="SendMeetingInvitations" type="t:CalendarItemCreateOrDeleteOperationType" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateItem" type="m:CreateItemType"/>
+
+ <xs:complexType name="UpdateItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SavedItemFolderId" type="t:TargetFolderIdType" minOccurs="0"/>
+ <xs:element name="ItemChanges" type="t:NonEmptyArrayOfItemChangesType"/>
+ </xs:sequence>
+ <xs:attribute name="ConflictResolution" type="t:ConflictResolutionType" use="required"/>
+ <xs:attribute name="MessageDisposition" type="t:MessageDispositionType" use="optional"/>
+ <xs:attribute name="SendMeetingInvitationsOrCancellations" type="t:CalendarItemUpdateOperationType" use="optional"/>
+ <xs:attribute name="SuppressReadReceipts" type="xs:boolean" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateItem" type="m:UpdateItemType"/>
+
+ <xs:complexType name="ItemInfoResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Items" type="t:ArrayOfRealItemsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="UpdateItemResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ItemInfoResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ConflictResults" type="t:ConflictResultsType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Updating a draft item in dumpster-->
+
+ <xs:complexType name="UpdateItemInRecoverableItemsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" />
+ <xs:element name="Updates" type="t:NonEmptyArrayOfItemChangeDescriptionsType" minOccurs="0"/>
+ <xs:element name="Attachments" type="t:NonEmptyArrayOfAttachmentsType" minOccurs="0"/>
+ <xs:element name="MakeItemImmutable" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateItemInRecoverableItems" type="m:UpdateItemInRecoverableItemsType"/>
+
+ <xs:complexType name="UpdateItemInRecoverableItemsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ItemInfoResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Attachments" type="t:ArrayOfAttachmentsType" minOccurs="0"/>
+ <xs:element name="ConflictResults" type="t:ConflictResultsType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Deleting an item. -->
+
+ <xs:complexType name="DeleteItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType"/>
+ </xs:sequence>
+ <xs:attribute name="DeleteType" type="t:DisposalType" use="required" />
+ <xs:attribute name="SendMeetingCancellations" type="t:CalendarItemCreateOrDeleteOperationType" use="optional"/>
+ <xs:attribute name="AffectedTaskOccurrences" type="t:AffectedTaskOccurrencesType" use="optional"/>
+ <xs:attribute name="SuppressReadReceipts" type="xs:boolean" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DeleteItem" type="m:DeleteItemType"/>
+
+ <!-- Attachment info response message -->
+
+ <xs:complexType name="AttachmentInfoResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Attachments" type="t:ArrayOfAttachmentsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Delete attachment response message -->
+
+ <xs:complexType name="DeleteAttachmentResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="RootItemId" type="t:RootItemIdType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Base for Move/Copy items between folders -->
+
+ <xs:complexType name="BaseMoveCopyItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ToFolderId" type="t:TargetFolderIdType"/>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType"/>
+ <xs:element name="ReturnNewItemIds" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- Move items between folders -->
+ <xs:complexType name="MoveItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseMoveCopyItemType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- Copy items between folders -->
+ <xs:complexType name="CopyItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseMoveCopyItemType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="MoveItem" type="m:MoveItemType"/>
+ <xs:element name="CopyItem" type="m:CopyItemType"/>
+
+ <!-- Archive Items to a folder in archive. -->
+ <xs:complexType name="ArchiveItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ArchiveSourceFolderId" type="t:TargetFolderIdType"/>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ArchiveItem" type="m:ArchiveItemType"/>
+
+ <!-- Send an email or post a note to a folder. -->
+ <xs:complexType name="SendItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType"/>
+ <xs:element name="SavedItemFolderId" type="t:TargetFolderIdType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="SaveItemToFolder" type="xs:boolean" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SendItem" type="m:SendItemType"/>
+
+ <!-- Response to a command to send or post an item -->
+ <xs:complexType name="SendItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SendItemResponse" type="m:SendItemResponseType"/>
+
+ <xs:complexType name="QueryStringType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="ResetCache" type="xs:boolean" use="optional"/>
+ <xs:attribute name="ReturnHighlightTerms" type="xs:boolean" use="optional"/>
+ <xs:attribute name="ReturnDeletedItems" type="xs:boolean" use="optional"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Enumerate items in a list of folders (Reading, 2) -->
+ <xs:complexType name="FindItemType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemShape" type="t:ItemResponseShapeType"/>
+ <xs:choice minOccurs="0">
+ <xs:element name="IndexedPageItemView" type="t:IndexedPageViewType"/>
+ <xs:element name="FractionalPageItemView" type="t:FractionalPageViewType"/>
+ <xs:element name="SeekToConditionPageItemView" type="t:SeekToConditionPageViewType"/>
+ <xs:element name="CalendarView" type="t:CalendarViewType"/>
+ <xs:element name="ContactsView" type="t:ContactsViewType"/>
+ </xs:choice>
+ <xs:choice minOccurs="0">
+ <xs:element name="GroupBy" type="t:GroupByType"/>
+ <xs:element name="DistinguishedGroupBy" type="t:DistinguishedGroupByType"/>
+ </xs:choice>
+ <xs:element name="Restriction" type="t:RestrictionType" minOccurs="0"/>
+ <xs:element name="SortOrder" type="t:NonEmptyArrayOfFieldOrdersType" minOccurs="0"/>
+ <xs:element name="ParentFolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType"/>
+ <xs:element name="QueryString" type="m:QueryStringType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="Traversal" type="t:ItemQueryTraversalType" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindItem" type="m:FindItemType"/>
+
+ <!-- Enumerate Conversation in a folder -->
+ <xs:complexType name="FindConversationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:choice minOccurs="0">
+ <xs:element name="IndexedPageItemView" type="t:IndexedPageViewType"/>
+ <xs:element name="SeekToConditionPageItemView" type="t:SeekToConditionPageViewType"/>
+ </xs:choice>
+ <xs:element name="SortOrder" type="t:NonEmptyArrayOfFieldOrdersType" minOccurs="0"/>
+ <xs:element name="ParentFolderId" type="t:TargetFolderIdType" minOccurs="1"/>
+ <xs:element name="MailboxScope" type="t:MailboxSearchLocationType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="QueryString" type="m:QueryStringType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ConversationShape" type="t:ConversationResponseShapeType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="Traversal" type="t:ConversationQueryTraversalType" use="optional"/>
+ <xs:attribute name="ViewFilter" type="t:ViewFilterType" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindConversation" type="m:FindConversationType"/>
+
+ <xs:complexType name="FindConversationResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Conversations" type="t:ArrayOfConversationsType" minOccurs="0" />
+ <xs:element name="HighlightTerms" type="t:ArrayOfHighlightTermsType" minOccurs="0" />
+ <xs:element name="TotalConversationsInView" type="xs:int" minOccurs="0" />
+ <xs:element name="IndexedOffset" type="xs:int" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindConversationResponse" type="m:FindConversationResponseMessageType"/>
+
+ <!-- Instant Search API v1.0 -->
+
+ <xs:complexType name="PerformInstantSearchRequest">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchSessionId" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ItemType" type="t:InstantSearchItemType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="QueryOptions" type="t:QueryOptionsType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SearchRequestId" type="xs:long" minOccurs="1" maxOccurs="1" />
+ <xs:element name="KqlQuery" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="FolderScope" type="t:ArrayOfFolderIdType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="DistinguishedFolderScope" type="t:ArrayOfDistinguishedFolderIdType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsDeepTraversal" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="WaitOnSearchResults" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="PerformInstantSearch" type="m:PerformInstantSearchRequest"/>
+
+ <xs:complexType name="PerformInstantSearchResponse">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Payload" type="t:InstantSearchPayloadType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="PerformInstantSearchResponse" type="m:PerformInstantSearchResponse"/>
+
+ <xs:complexType name="EndInstantSearchSessionRequest">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SessionId" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="EndInstantSearchSession" type="m:EndInstantSearchSessionRequest"/>
+
+
+ <!-- Apply Actions to a conversation -->
+
+ <xs:complexType name="ApplyConversationActionType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ConversationActions" type="t:NonEmptyArrayOfApplyConversationActionType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="ApplyConversationAction" type="m:ApplyConversationActionType"/>
+
+ <!-- ApplyConversationAction response -->
+ <xs:complexType name="ApplyConversationActionResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="ApplyConversationActionResponse" type="m:ApplyConversationActionResponseType"/>
+
+ <xs:complexType name="ApplyConversationActionResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Enumerate People in a folder -->
+ <xs:complexType name="FindPeopleType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="PersonaShape" type="t:PersonaResponseShapeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IndexedPageItemView" type="t:IndexedPageViewType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Restriction" type="t:RestrictionType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AggregationRestriction" type="t:RestrictionType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SortOrder" type="t:NonEmptyArrayOfFieldOrdersType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ParentFolderId" type="t:TargetFolderIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="QueryString" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SearchPeopleSuggestionIndex" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="TopicQueryString" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Context" type="t:ArrayOfContextProperty" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="QuerySources" type="t:ArrayOfPeopleQuerySource" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindPeople" type="m:FindPeopleType"/>
+
+ <xs:complexType name="FindPeopleResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="People" type="t:ArrayOfPeopleType" minOccurs="0"/>
+ <xs:element name="TotalNumberOfPeopleInView" type="xs:int" minOccurs="0" />
+ <xs:element name="FirstMatchingRowIndex" type="xs:int" minOccurs="0" />
+ <xs:element name="FirstLoadedRowIndex" type="xs:int" minOccurs="0" />
+ <xs:element name="TransactionId" type="t:GuidType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindPeopleResponse" type="m:FindPeopleResponseMessageType"/>
+
+ <!-- Enumerate Tags in a folder -->
+ <xs:complexType name="FindTagsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="IndexedPageItemView" type="t:IndexedPageViewType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SortOrder" type="t:NonEmptyArrayOfFieldOrdersType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="QueryString" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Context" type="t:ArrayOfContextProperty" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindTags" type="m:FindTagsType"/>
+
+ <xs:complexType name="FindTagsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Tags" type="t:ArrayOfStringsType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindTagsResponse" type="m:FindTagsResponseMessageType"/>
+
+ <!-- Add tag -->
+ <xs:complexType name="AddTagType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Tag" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="AppName" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddTag" type="m:AddTagType"/>
+
+ <xs:complexType name="AddTagResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="WasSuccessful" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddTagResponse" type="m:AddTagResponseMessageType"/>
+
+ <!-- Hide tag -->
+ <xs:complexType name="HideTagType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Tag" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="HideTag" type="m:HideTagType"/>
+
+ <xs:complexType name="HideTagResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="WasSuccessful" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="HideTagResponse" type="m:HideTagResponseMessageType"/>
+
+ <!-- Get a specific Persona -->
+ <xs:complexType name="GetPersonaType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="PersonaId" type="t:ItemIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EmailAddress" type="t:EmailAddressType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ParentFolderId" type="t:TargetFolderIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ItemLinkId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfPathsToElementType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetPersona" type="m:GetPersonaType"/>
+
+ <xs:complexType name="GetPersonaResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Persona" type="t:PersonaType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetPersonaResponseMessage" type="m:GetPersonaResponseMessageType"/>
+
+ <!-- Creating attachments -->
+ <xs:complexType name="CreateAttachmentType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ParentItemId" type="t:ItemIdType" minOccurs="1" />
+ <xs:element name="Attachments" type="t:NonEmptyArrayOfAttachmentsType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateAttachment" type="m:CreateAttachmentType" />
+ <xs:complexType name="CreateAttachmentResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateAttachmentResponse" type="m:CreateAttachmentResponseType"/>
+
+ <!-- Deleting attachments -->
+ <xs:complexType name="DeleteAttachmentType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="AttachmentIds" type="t:NonEmptyArrayOfRequestAttachmentIdsType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteAttachment" type="m:DeleteAttachmentType" />
+ <xs:complexType name="DeleteAttachmentResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteAttachmentResponse" type="m:DeleteAttachmentResponseType"/>
+
+ <!-- Accessing attachments -->
+ <xs:complexType name="GetAttachmentType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="AttachmentShape" type="t:AttachmentResponseShapeType" minOccurs="0"/>
+ <xs:element name="AttachmentIds" type="t:NonEmptyArrayOfRequestAttachmentIdsType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetAttachment" type="m:GetAttachmentType" />
+ <xs:complexType name="GetAttachmentResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetAttachmentResponse" type="m:GetAttachmentResponseType"/>
+
+ <xs:complexType name="CreateItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateItemResponse" type="m:CreateItemResponseType"/>
+ <xs:complexType name="UpdateItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UpdateItemResponse" type="m:UpdateItemResponseType"/>
+ <xs:complexType name="UpdateItemInRecoverableItemsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UpdateItemInRecoverableItemsResponse" type="m:UpdateItemInRecoverableItemsResponseType"/>
+ <xs:complexType name="GetItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetItemResponse" type="m:GetItemResponseType"/>
+ <xs:complexType name="MoveItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="CopyItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="MoveItemResponse" type="m:MoveItemResponseType"/>
+ <xs:element name="CopyItemResponse" type="m:CopyItemResponseType"/>
+
+ <!-- DeleteItem response -->
+ <xs:complexType name="DeleteItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteItemResponse" type="m:DeleteItemResponseType"/>
+
+ <xs:complexType name="DeleteItemResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- FindItem response type-->
+ <xs:complexType name="FindItemResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="RootFolder" type="t:FindItemParentType" minOccurs="0"/>
+ <xs:element name="HighlightTerms" type="t:ArrayOfHighlightTermsType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="FindItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindItemResponse" type="m:FindItemResponseType"/>
+
+ <xs:complexType name="ArchiveItemResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ArchiveItemResponse" type="m:ArchiveItemResponseType"/>
+
+ <xs:complexType name="GetClientAccessTokenType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="TokenRequests" type="t:NonEmptyArrayOfClientAccessTokenRequestsType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetClientAccessToken" type="m:GetClientAccessTokenType"/>
+
+ <xs:complexType name="GetClientAccessTokenResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Token" type="t:ClientAccessTokenType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="GetClientAccessTokenResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetClientAccessTokenResponse" type="m:GetClientAccessTokenResponseType"/>
+
+ <!-- CRUD operations for focused/other overrides -->
+ <!-- Retrieve overrides -->
+ <xs:complexType name="GetFocusedOtherOverridesRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetFocusedOtherOverrides" type="m:GetFocusedOtherOverridesRequestType" />
+
+ <xs:complexType name="GetFocusedOtherOverridesResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Overrides" type="t:ArrayOfInferenceClassificationOverridesType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetFocusedOtherOverridesResponse" type="m:GetFocusedOtherOverridesResponseType"/>
+
+ <!-- Create or update override -->
+ <xs:complexType name="CreateOrUpdateFocusedOtherOverrideRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SenderSmtpAddress" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SenderDisplayName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="AlwaysClassifyAs" type="t:InferenceClassificationType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateOrUpdateFocusedOtherOverride" type="m:CreateOrUpdateFocusedOtherOverrideRequestType" />
+
+ <xs:complexType name="CreateOrUpdateFocusedOtherOverrideResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Override" type="t:InferenceClassificationOverrideType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateOrUpdateFocusedOtherOverrideResponse" type="m:CreateOrUpdateFocusedOtherOverrideResponseType"/>
+
+ <!-- Delete FocusedOtherOverride -->
+ <xs:complexType name="DeleteFocusedOtherOverrideRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Id" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteFocusedOtherOverride" type="m:DeleteFocusedOtherOverrideRequestType" />
+
+
+ <xs:complexType name="DeleteFocusedOtherOverrideResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Override" type="t:InferenceClassificationOverrideType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteFocusedOtherOverrideResponse" type="m:DeleteFocusedOtherOverrideResponseType"/>
+
+ <!-- Util Service messages -->
+ <!-- ResolveNames request -->
+
+ <xs:complexType name="ResolveNamesType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ParentFolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType" minOccurs="0"/>
+ <xs:element name="UnresolvedEntry" type="t:NonEmptyStringType" />
+ </xs:sequence>
+ <xs:attribute name="ReturnFullContactData" type="xs:boolean" use="required" />
+ <xs:attribute name="SearchScope" type="t:ResolveNamesSearchScopeType" default="ActiveDirectoryContacts" />
+ <xs:attribute name="ContactDataShape" type="t:DefaultShapeNamesType" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="ResolveNames" type="m:ResolveNamesType"/>
+
+ <!-- ResolveNames response -->
+
+ <xs:complexType name="ResolveNamesResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ResolutionSet" type="t:ArrayOfResolutionType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ResolveNamesResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="ResolveNamesResponse" type="m:ResolveNamesResponseType"/>
+
+ <!-- GetPasswordExpirationDate -->
+
+ <xs:complexType name="GetPasswordExpirationDateType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="MailboxSmtpAddress" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetPasswordExpirationDate" type="m:GetPasswordExpirationDateType"/>
+
+ <!-- GetPasswordExpirationDate response message -->
+
+ <xs:complexType name="GetPasswordExpirationDateResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="PasswordExpirationDate" type="xs:dateTime"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetPasswordExpirationDateResponse" type="m:GetPasswordExpirationDateResponseMessageType"/>
+
+ <!-- MailTips -->
+
+ <xs:complexType name="GetMailTipsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SendingAs" type="t:EmailAddressType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Recipients" type="t:ArrayOfRecipientsType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="MailTipsRequested" type="t:MailTipTypes" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetMailTips" type="m:GetMailTipsType"/>
+
+ <xs:element name="GetMailTipsResponse" type="m:GetMailTipsResponseMessageType"/>
+
+ <xs:complexType name="GetMailTipsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ResponseMessages" type="m:ArrayOfMailTipsResponseMessageType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfMailTipsResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MailTipsResponseMessageType" type="m:MailTipsResponseMessageType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MailTipsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MailTips" type="t:MailTips" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- PlayOnPhone Request -->
+ <xs:complexType name="PlayOnPhoneType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="DialString" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="PlayOnPhone" type="m:PlayOnPhoneType"/>
+
+ <!-- PlayOnPhone Response -->
+ <xs:complexType name="PlayOnPhoneResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="PhoneCallId" type="t:PhoneCallIdType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="PlayOnPhoneResponse" type="m:PlayOnPhoneResponseMessageType"/>
+
+ <!-- GetPhoneCallInformation Request -->
+ <xs:complexType name="GetPhoneCallInformationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="PhoneCallId" type="t:PhoneCallIdType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetPhoneCallInformation" type="m:GetPhoneCallInformationType"/>
+
+ <!-- GetPhoneCallInformation Response -->
+ <xs:complexType name="GetPhoneCallInformationResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="PhoneCallInformation" type="t:PhoneCallInformationType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetPhoneCallInformationResponse" type="m:GetPhoneCallInformationResponseMessageType"/>
+
+ <!-- DisconnectPhoneCall Request -->
+ <xs:complexType name="DisconnectPhoneCallType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="PhoneCallId" type="t:PhoneCallIdType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DisconnectPhoneCall" type="m:DisconnectPhoneCallType"/>
+
+ <!-- DisconnectPhoneCall Response -->
+ <xs:complexType name="DisconnectPhoneCallResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DisconnectPhoneCallResponse" type="m:DisconnectPhoneCallResponseMessageType"/>
+
+ <!-- ExpandDL request -->
+
+ <xs:complexType name="ExpandDLType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Mailbox" type="t:EmailAddressType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="ExpandDL" type="m:ExpandDLType"/>
+
+ <!-- ExpandDL response -->
+
+ <xs:complexType name="ExpandDLResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="DLExpansion" type="t:ArrayOfDLExpansionType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attributeGroup ref="t:FindResponsePagingAttributes" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ExpandDLResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="ExpandDLResponse" type="m:ExpandDLResponseType"/>
+
+ <!-- Get TimeZones -->
+
+ <xs:complexType name="GetServerTimeZonesType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Ids" type="t:NonEmptyArrayOfTimeZoneIdType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="ReturnFullTimeZoneData" type="xs:boolean" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetServerTimeZones" type="m:GetServerTimeZonesType"/>
+
+ <!-- TimeZones response -->
+
+ <xs:complexType name="GetServerTimeZonesResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="TimeZoneDefinitions" type="t:ArrayOfTimeZoneDefinitionType" minOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="GetServerTimeZonesResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetServerTimeZonesResponse" type="m:GetServerTimeZonesResponseType"/>
+
+ <!-- CreateManagedFolder request type. -->
+ <xs:complexType name="CreateManagedFolderRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="FolderNames" type="t:NonEmptyArrayOfFolderNamesType"/>
+ <xs:element name="Mailbox" type="t:EmailAddressType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateManagedFolder" type="m:CreateManagedFolderRequestType"/>
+ <!-- CreateManagedFolder response type. -->
+ <xs:complexType name="CreateManagedFolderResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="CreateManagedFolderResponse" type="m:CreateManagedFolderResponseType"/>
+ <!-- Subscribe request -->
+ <xs:complexType name="SubscribeType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:choice>
+ <xs:element name="PullSubscriptionRequest" type="t:PullSubscriptionRequestType"/>
+ <xs:element name="PushSubscriptionRequest" type="t:PushSubscriptionRequestType"/>
+ <xs:element name="StreamingSubscriptionRequest" type="t:StreamingSubscriptionRequestType"/>
+ </xs:choice>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="Subscribe" type="m:SubscribeType"/>
+ <!-- Subscribe response -->
+ <xs:complexType name="SubscribeResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="SubscriptionId" type="t:SubscriptionIdType" minOccurs="0"/>
+ <xs:element name="Watermark" type="t:WatermarkType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="SubscribeResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SubscribeResponse" type="m:SubscribeResponseType"/>
+ <!-- Unsubscribe request -->
+ <xs:complexType name="UnsubscribeType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SubscriptionId" type="t:SubscriptionIdType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="Unsubscribe" type="m:UnsubscribeType"/>
+ <!-- Unsubscribe response -->
+ <xs:complexType name="UnsubscribeResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UnsubscribeResponse" type="m:UnsubscribeResponseType"/>
+ <!-- GetEvents request -->
+ <xs:complexType name="GetEventsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SubscriptionId" type="t:SubscriptionIdType"/>
+ <xs:element name="Watermark" type="t:WatermarkType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetEvents" type="m:GetEventsType"/>
+ <!-- GetEvents response -->
+ <xs:complexType name="GetEventsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Notification" type="t:NotificationType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="GetEventsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetEventsResponse" type="m:GetEventsResponseType"/>
+
+ <!-- GetStreamingEvents request -->
+ <xs:complexType name="GetStreamingEventsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SubscriptionIds"
+ type="t:NonEmptyArrayOfSubscriptionIdsType"/>
+ <xs:element name="ConnectionTimeout"
+ type="t:StreamingSubscriptionConnectionTimeoutType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetStreamingEvents" type="m:GetStreamingEventsType"/>
+ <!-- GetStreamingEvents response -->
+ <xs:complexType name="GetStreamingEventsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Notifications" type="t:NonEmptyArrayOfNotificationsType"
+ minOccurs="0"/>
+ <xs:element name="ErrorSubscriptionIds"
+ type="t:NonEmptyArrayOfSubscriptionIdsType" minOccurs="0"/>
+ <xs:element name="ConnectionStatus"
+ type="t:ConnectionStatusType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="GetStreamingEventsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetStreamingEventsResponse" type="m:GetStreamingEventsResponseType"/>
+
+ <!-- SendNotification request -->
+ <xs:complexType name="SendNotificationResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Notification" type="t:NotificationType" minOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SendNotificationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SendNotification" type="m:SendNotificationResponseType"/>
+
+ <!-- SendNotification response -->
+ <xs:complexType name="SendNotificationResultType">
+ <xs:sequence>
+ <xs:element name="SubscriptionStatus" type="t:SubscriptionStatusType"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="SendNotificationResult" type="m:SendNotificationResultType"/>
+
+ <!-- Sync Service messages. -->
+ <xs:complexType name="SyncFolderHierarchyType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="FolderShape" type="t:FolderResponseShapeType" minOccurs="1"/>
+ <xs:element name="SyncFolderId" type="t:TargetFolderIdType" minOccurs="0" />
+ <xs:element name="SyncState" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SyncFolderHierarchy" type="m:SyncFolderHierarchyType"/>
+
+ <xs:complexType name="SyncFolderHierarchyResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="SyncState" type="xs:string" minOccurs="0"/>
+ <xs:element name="IncludesLastFolderInRange" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="Changes" type="t:SyncFolderHierarchyChangesType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="SyncFolderHierarchyResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SyncFolderHierarchyResponse" type="m:SyncFolderHierarchyResponseType"/>
+
+ <xs:complexType name="SyncFolderItemsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemShape" type="t:ItemResponseShapeType" minOccurs="1"/>
+ <xs:element name="SyncFolderId" type="t:TargetFolderIdType" minOccurs="1"/>
+ <xs:element name="SyncState" type="xs:string" minOccurs="0"/>
+ <xs:element name="Ignore" type="t:ArrayOfBaseItemIdsType" minOccurs="0"/>
+ <xs:element name="MaxChangesReturned" type="t:MaxSyncChangesReturnedType" minOccurs="1"/>
+ <xs:element name="SyncScope" type="t:SyncFolderItemsScopeType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SyncFolderItems" type="m:SyncFolderItemsType"/>
+
+ <xs:complexType name="SyncFolderItemsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="SyncState" type="xs:string" minOccurs="0"/>
+ <xs:element name="IncludesLastItemInRange" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="Changes" type="t:SyncFolderItemsChangesType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="SyncFolderItemsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SyncFolderItemsResponse" type="m:SyncFolderItemsResponseType"/>
+
+ <!-- Availability Service message definitions -->
+
+ <!-- GetUserAvailabilityRequest -->
+
+ <xs:complexType name="GetUserAvailabilityRequestType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" ref="t:TimeZone" />
+ <xs:element name="MailboxDataArray" type="t:ArrayOfMailboxData" />
+ <xs:element minOccurs="0" maxOccurs="1" ref="t:FreeBusyViewOptions" />
+ <xs:element minOccurs="0" maxOccurs="1" ref="t:SuggestionsViewOptions" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetUserAvailabilityRequest" type="m:GetUserAvailabilityRequestType" />
+
+ <!-- FreeBusyResponse -->
+
+ <xs:complexType name="FreeBusyResponseType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="ResponseMessage" type="m:ResponseMessageType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="FreeBusyView" type="t:FreeBusyView" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfFreeBusyResponse">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="FreeBusyResponse" type="m:FreeBusyResponseType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SuggestionsResponseType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="ResponseMessage" type="m:ResponseMessageType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="SuggestionDayResultArray" type="t:ArrayOfSuggestionDayResult" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- GetUserAvailabilityResponse -->
+
+ <xs:complexType name="GetUserAvailabilityResponseType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="FreeBusyResponseArray" type="m:ArrayOfFreeBusyResponse" />
+ <xs:element minOccurs="0" maxOccurs="1" name="SuggestionsResponse" type="m:SuggestionsResponseType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="GetUserAvailabilityResponse" type="m:GetUserAvailabilityResponseType" />
+
+ <!-- GetUserOofSettingsRequest -->
+
+ <xs:complexType name="GetUserOofSettingsRequest">
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" ref="t:Mailbox" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetUserOofSettingsRequest" type="m:GetUserOofSettingsRequest" />
+
+ <!-- GetUserOofSettingsResponse -->
+
+ <xs:complexType name="GetUserOofSettingsResponse">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="ResponseMessage" type="m:ResponseMessageType" />
+ <xs:element minOccurs="0" maxOccurs="1" ref="t:OofSettings" />
+ <xs:element minOccurs="0" maxOccurs="1" name="AllowExternalOof" type="t:ExternalAudience" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="GetUserOofSettingsResponse" type="m:GetUserOofSettingsResponse" />
+
+ <!-- SetUserOofSettingsRequest -->
+
+ <xs:complexType name="SetUserOofSettingsRequest">
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" ref="t:Mailbox" />
+ <xs:element minOccurs="1" maxOccurs="1" ref="t:UserOofSettings" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetUserOofSettingsRequest" type="m:SetUserOofSettingsRequest" />
+
+ <!-- SetUserOofSettingsResponse -->
+
+ <xs:complexType name="SetUserOofSettingsResponse">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="ResponseMessage" type="m:ResponseMessageType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="SetUserOofSettingsResponse" type="m:SetUserOofSettingsResponse" />
+
+ <!-- ConvertId web method and response -->
+ <xs:complexType name="ConvertIdType">
+ <xs:annotation>
+ <xs:documentation>
+ Converts the passed source ids into the destination format. Change keys are not
+ returned.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SourceIds" type="t:NonEmptyArrayOfAlternateIdsType" minOccurs ="1" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="DestinationFormat" type="t:IdFormatType" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ConvertId" type="m:ConvertIdType"/>
+
+ <xs:complexType name="ConvertIdResponseType">
+ <xs:annotation>
+ <xs:documentation>Response type for the ConvertId web method</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ConvertIdResponse" type="m:ConvertIdResponseType"/>
+
+ <xs:complexType name="ConvertIdResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response Message for a single id conversion in the ConvertId web method. Note
+ that the AlternateId element will be missing in the case of an error.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="AlternateId" type="t:AlternateIdBaseType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- GetDelegate web method and response -->
+ <xs:complexType name="GetDelegateType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateType">
+ <xs:sequence>
+ <xs:element name="UserIds" type="t:ArrayOfUserIdType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ <xs:attribute name="IncludePermissions" type="xs:boolean" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetDelegate" type="m:GetDelegateType"/>
+
+ <xs:complexType name="GetDelegateResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateResponseMessageType">
+ <xs:sequence>
+ <xs:element name="DeliverMeetingRequests" type="t:DeliverMeetingRequestsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfDelegateUserResponseMessageType">
+ <xs:sequence>
+ <xs:element name="DelegateUserResponseMessageType" type="m:DelegateUserResponseMessageType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DelegateUserResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="DelegateUser" type="t:DelegateUserType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetDelegateResponse" type="m:GetDelegateResponseMessageType"/>
+
+ <!-- AddDelegate web method and response -->
+ <xs:complexType name="AddDelegateType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateType">
+ <xs:sequence>
+ <xs:element name="DelegateUsers" type="t:ArrayOfDelegateUserType" />
+ <xs:element name="DeliverMeetingRequests" type="t:DeliverMeetingRequestsType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddDelegate" type="m:AddDelegateType"/>
+
+ <!-- AddDelegate response -->
+ <xs:complexType name="BaseDelegateResponseMessageType" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ResponseMessages" type="m:ArrayOfDelegateUserResponseMessageType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="BaseDelegateType" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Mailbox" type="t:EmailAddressType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AddDelegateResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddDelegateResponse" type="m:AddDelegateResponseMessageType"/>
+
+ <!-- RemoveDelegate request -->
+ <xs:complexType name="RemoveDelegateType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateType">
+ <xs:sequence>
+ <xs:element name="UserIds" type="t:ArrayOfUserIdType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveDelegate" type="m:RemoveDelegateType"/>
+
+ <!-- RemoveDelegate response -->
+ <xs:complexType name="RemoveDelegateResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveDelegateResponse" type="m:RemoveDelegateResponseMessageType"/>
+
+ <!-- UpdateDelegate request -->
+ <xs:complexType name="UpdateDelegateType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateType">
+ <xs:sequence>
+ <xs:element name="DelegateUsers" type="t:ArrayOfDelegateUserType" minOccurs="0" />
+ <xs:element name="DeliverMeetingRequests" type="t:DeliverMeetingRequestsType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateDelegate" type="m:UpdateDelegateType"/>
+
+ <!-- UpdateDelegate response -->
+ <xs:complexType name="UpdateDelegateResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseDelegateResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+
+ <xs:element name="UpdateDelegateResponse" type="m:UpdateDelegateResponseMessageType"/>
+
+ <!-- GetSharingMetadata request -->
+ <xs:complexType name="GetSharingMetadataType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="IdOfFolderToShare" type="t:FolderIdType"/>
+ <xs:element name="SenderSmtpAddress" type="t:NonEmptyStringType"/>
+ <xs:element name="Recipients" type="t:ArrayOfSmtpAddressType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetSharingMetadata" type="m:GetSharingMetadataType"/>
+
+ <!-- GetSharingMetadata response -->
+ <xs:complexType name="GetSharingMetadataResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence minOccurs="0">
+ <xs:element name="EncryptedSharedFolderDataCollection" type="t:ArrayOfEncryptedSharedFolderDataType"/>
+ <xs:element name="InvalidRecipients" type="t:ArrayOfInvalidRecipientsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetSharingMetadataResponse" type="m:GetSharingMetadataResponseMessageType"/>
+
+ <!-- RefreshSharingFolder request -->
+ <xs:complexType name="RefreshSharingFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SharingFolderId" type="t:FolderIdType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="RefreshSharingFolder" type="m:RefreshSharingFolderType"/>
+
+ <!-- RefreshSharingFolder response -->
+ <xs:complexType name="RefreshSharingFolderResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="RefreshSharingFolderResponse" type="m:RefreshSharingFolderResponseMessageType"/>
+
+ <!-- GetSharingFolder request -->
+ <xs:complexType name="GetSharingFolderType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SmtpAddress" type="t:NonEmptyStringType"/>
+ <xs:element name="DataType" type="t:SharingDataType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SharedFolderId" type="t:NonEmptyStringType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetSharingFolder" type="m:GetSharingFolderType"/>
+
+ <!-- GetSharingFolder response -->
+ <xs:complexType name="GetSharingFolderResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence minOccurs="0">
+ <xs:element name="SharingFolderId" type="t:FolderIdType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetSharingFolderResponse" type="m:GetSharingFolderResponseMessageType"/>
+
+ <!-- CreateUserConfiguration request -->
+ <xs:complexType name="CreateUserConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="UserConfiguration" type="t:UserConfigurationType" minOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="CreateUserConfiguration" type="m:CreateUserConfigurationType"/>
+
+ <!-- CreateUserConfiguration response -->
+ <xs:complexType name="CreateUserConfigurationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="CreateUserConfigurationResponse" type="m:CreateUserConfigurationResponseType"/>
+
+ <!-- DeleteUserConfiguration request -->
+ <xs:complexType name="DeleteUserConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="UserConfigurationName" type="t:UserConfigurationNameType" minOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DeleteUserConfiguration" type="m:DeleteUserConfigurationType"/>
+
+ <!-- DeleteUserConfiguration response -->
+ <xs:complexType name="DeleteUserConfigurationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DeleteUserConfigurationResponse" type="m:DeleteUserConfigurationResponseType"/>
+
+ <!-- GetUserConfiguration request -->
+ <xs:complexType name="GetUserConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="UserConfigurationName" type="t:UserConfigurationNameType" minOccurs="1" />
+ <xs:element name="UserConfigurationProperties" type="t:UserConfigurationPropertyType" minOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetUserConfiguration" type="m:GetUserConfigurationType"/>
+
+ <!-- GetUserConfiguration response -->
+ <xs:complexType name="GetUserConfigurationResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="UserConfiguration" type="t:UserConfigurationType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="GetUserConfigurationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetUserConfigurationResponse" type="m:GetUserConfigurationResponseType"/>
+
+ <!-- GetSpecificUserConfiguration request -->
+ <xs:complexType name="GetSpecificUserConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="UserConfigurationName" type="t:UserConfigurationNameType" minOccurs="1" />
+ <xs:element name="UserConfigurationProperties" type="t:UserConfigurationPropertyType" minOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetSpecificUserConfiguration" type="m:GetSpecificUserConfigurationType"/>
+
+ <!-- GetSpecificUserConfiguration response -->
+ <xs:complexType name="GetSpecificUserConfigurationResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="UserConfiguration" type="t:UserConfigurationType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="GetSpecificUserConfigurationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetSpecificUserConfigurationResponse" type="m:GetSpecificUserConfigurationResponseType"/>
+
+ <!-- UpdateUserConfiguration request -->
+ <xs:complexType name="UpdateUserConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="UserConfiguration" type="t:UserConfigurationType" minOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateUserConfiguration" type="m:UpdateUserConfigurationType"/>
+
+ <!-- UpdateUserConfiguration response -->
+ <xs:complexType name="UpdateUserConfigurationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateUserConfigurationResponse" type="m:UpdateUserConfigurationResponseType"/>
+
+ <!-- TeamMailbox requests -->
+ <xs:complexType name="SetTeamMailboxRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="EmailAddress" type="t:EmailAddressType" />
+ <xs:element name="SharePointSiteUrl" type="xs:string" />
+ <xs:element name="State" type="t:TeamMailboxLifecycleStateType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SetTeamMailbox" type="m:SetTeamMailboxRequestType" />
+
+ <xs:complexType name="UnpinTeamMailboxRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="EmailAddress" type="t:EmailAddressType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UnpinTeamMailbox" type="m:UnpinTeamMailboxRequestType" />
+
+ <!-- TeamMailbox responses -->
+ <xs:complexType name="SetTeamMailboxResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SetTeamMailboxResponse" type="m:SetTeamMailboxResponseMessageType" />
+
+ <xs:complexType name="UnpinTeamMailboxResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UnpinTeamMailboxResponse" type="m:UnpinTeamMailboxResponseMessageType" />
+
+ <!-- Get Rooms Service Message Definitions -->
+
+ <!-- GetRoomLists Request -->
+ <xs:complexType name="GetRoomListsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType" />
+ <!-- We Don't Need Input For GetRoomLists. -->
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetRoomLists" type="m:GetRoomListsType"/>
+
+ <!-- GetRoomLists Response -->
+ <xs:complexType name="GetRoomListsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="RoomLists" type="t:ArrayOfEmailAddressesType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetRoomListsResponse" type="m:GetRoomListsResponseMessageType"/>
+
+ <!-- GetRoomsRequest -->
+ <xs:complexType name="GetRoomsType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <!--Input Will Be A Single RoomList of Type EmailAddressType-->
+ <xs:element name="RoomList" type="t:EmailAddressType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetRooms" type="m:GetRoomsType" />
+
+ <!-- GetRoomsResponse -->
+ <xs:complexType name="GetRoomsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <!--Output Should Be Rooms of Type ArrayOfRoomsType, Created In Types.xsd, Which Contains EmailAddress-->
+ <!--Keep In Mind, Availability Service Requests For ArrayOfMailboxData-->
+ <xs:element name="Rooms" type="t:ArrayOfRoomsType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetRoomsResponse" type="m:GetRoomsResponseMessageType" />
+
+ <!-- GetRemindersRequest -->
+ <xs:complexType name="GetRemindersType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="BeginTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EndTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MaxItems" minOccurs="0" maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="0"/>
+ <xs:maxInclusive value="200"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ <xs:element name="ReminderType" minOccurs="0" maxOccurs="1">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="All" />
+ <xs:enumeration value="Current" />
+ <xs:enumeration value="Old" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:element>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetReminders" type="m:GetRemindersType" />
+
+ <!-- GetRemindersResponse -->
+ <xs:complexType name="GetRemindersResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Reminders" type="t:ArrayOfRemindersType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetRemindersResponse" type="m:GetRemindersResponseMessageType" />
+
+ <!-- PerformReminderActionRequest -->
+ <xs:complexType name="PerformReminderActionType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ReminderItemActions" type="t:NonEmptyArrayOfReminderItemActionType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="PerformReminderAction" type="m:PerformReminderActionType" />
+
+ <!-- PerformReminderActionResponse-->
+ <xs:complexType name="PerformReminderActionResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="UpdatedItemIds" type="t:NonEmptyArrayOfItemIdsType" minOccurs ="1" maxOccurs ="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="PerformReminderActionResponse" type="m:PerformReminderActionResponseMessageType" />
+
+ <!-- GetServiceConfiguration -->
+
+ <xs:complexType name="ArrayOfServiceConfigurationType">
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="ConfigurationName" type="t:ServiceConfigurationType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="GetServiceConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="ActingAs" type="t:EmailAddressType"/>
+ <xs:element minOccurs="1" maxOccurs="1" name="RequestedConfiguration" type="m:ArrayOfServiceConfigurationType"/>
+ <xs:element minOccurs="0" maxOccurs="1" name="ConfigurationRequestDetails" type="t:ConfigurationRequestDetailsType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetServiceConfiguration" type="m:GetServiceConfigurationType"/>
+
+ <xs:element name="GetServiceConfigurationResponse" type="m:GetServiceConfigurationResponseMessageType"/>
+
+ <xs:complexType name="GetServiceConfigurationResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ResponseMessages" type="m:ArrayOfServiceConfigurationResponseMessageType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfServiceConfigurationResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ServiceConfigurationResponseMessageType" type="m:ServiceConfigurationResponseMessageType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ServiceConfigurationResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MailTipsConfiguration" type="t:MailTipsServiceConfiguration" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="UnifiedMessagingConfiguration" type="t:UnifiedMessageServiceConfiguration" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ProtectionRulesConfiguration" type="t:ProtectionRulesServiceConfiguration" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="PolicyNudgeRulesConfiguration" type="t:PolicyNudgeRulesServiceConfiguration" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SharePointURLsConfiguration" type="t:SharePointURLsServiceConfiguration" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- MessageTracking -->
+ <xs:complexType name="FindMessageTrackingReportRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:all>
+ <xs:element name="Scope" type="t:NonEmptyStringType" />
+ <xs:element name="Domain" type="t:NonEmptyStringType" />
+ <xs:element name="Sender" type="t:EmailAddressType" minOccurs="0"/>
+ <xs:element name="PurportedSender" type="t:EmailAddressType" minOccurs="0" />
+ <xs:element name="Recipient" type="t:EmailAddressType" minOccurs="0"/>
+ <xs:element name="Subject" type="xs:string" minOccurs="0"/>
+ <xs:element name="StartDateTime" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="EndDateTime" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="MessageId" type="t:NonEmptyStringType" minOccurs="0"/>
+ <xs:element name="FederatedDeliveryMailbox" type="t:EmailAddressType" minOccurs="0" />
+ <xs:element name="DiagnosticsLevel" type="xs:string" minOccurs="0" />
+ <xs:element name="ServerHint" type="xs:string" minOccurs="0" />
+ <xs:element name="Properties" type="t:ArrayOfTrackingPropertiesType" minOccurs="0" />
+ </xs:all>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindMessageTrackingReport" type="m:FindMessageTrackingReportRequestType"/>
+
+ <xs:complexType name="FindMessageTrackingReportResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Diagnostics" type="t:ArrayOfStringsType" minOccurs="0"/>
+ <xs:element name="MessageTrackingSearchResults" type="t:ArrayOfFindMessageTrackingSearchResultType" minOccurs="0" />
+ <xs:element name="ExecutedSearchScope" type="xs:string" minOccurs="0" />
+ <xs:element name="Errors" type="t:ArrayOfArraysOfTrackingPropertiesType" minOccurs="0" />
+ <xs:element name="Properties" type="t:ArrayOfTrackingPropertiesType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindMessageTrackingReportResponse" type="m:FindMessageTrackingReportResponseMessageType" />
+
+ <xs:complexType name="GetMessageTrackingReportRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:all>
+ <xs:element name="Scope" type="t:NonEmptyStringType" />
+ <xs:element name="ReportTemplate" type="t:MessageTrackingReportTemplateType" />
+ <xs:element name="RecipientFilter" type="t:EmailAddressType" minOccurs="0"/>
+ <xs:element name="MessageTrackingReportId" type="t:NonEmptyStringType" />
+ <xs:element name="ReturnQueueEvents" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="DiagnosticsLevel" type="xs:string" minOccurs="0" />
+ <xs:element name="Properties" type="t:ArrayOfTrackingPropertiesType" minOccurs="0" />
+ </xs:all>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetMessageTrackingReport" type="m:GetMessageTrackingReportRequestType" />
+
+ <xs:complexType name="GetMessageTrackingReportResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MessageTrackingReport" type="t:MessageTrackingReportType" minOccurs="0" />
+ <xs:element name="Diagnostics" type="t:ArrayOfStringsType" minOccurs="0"/>
+ <xs:element name="Errors" type="t:ArrayOfArraysOfTrackingPropertiesType" minOccurs="0" />
+ <xs:element name="Properties" type="t:ArrayOfTrackingPropertiesType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetMessageTrackingReportResponse" type="m:GetMessageTrackingReportResponseMessageType" />
+
+ <!-- Inbox Rules -->
+ <xs:complexType name="GetInboxRulesRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="MailboxSmtpAddress" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetInboxRules" type="m:GetInboxRulesRequestType" />
+
+ <xs:complexType name="GetInboxRulesResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="OutlookRuleBlobExists" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="InboxRules" type="t:ArrayOfRulesType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetInboxRulesResponse" type="m:GetInboxRulesResponseType" />
+
+ <xs:complexType name="UpdateInboxRulesRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="MailboxSmtpAddress" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="RemoveOutlookRuleBlob" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Operations" type="t:ArrayOfRuleOperationsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateInboxRules" type="m:UpdateInboxRulesRequestType" />
+
+ <xs:complexType name="UpdateInboxRulesResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="RuleOperationErrors" type="t:ArrayOfRuleOperationErrorsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateInboxRulesResponse" type="m:UpdateInboxRulesResponseType" />
+
+ <!-- FindMailboxStatisticsByKeywords web method and response -->
+ <xs:complexType name="FindMailboxStatisticsByKeywordsType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the FindMailboxStatisticsByKeywords web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Mailboxes" type="t:ArrayOfUserMailboxesType" minOccurs="1"/>
+ <xs:element name="Keywords" type="t:ArrayOfStringsType" minOccurs="1"/>
+ <xs:element name="Language" type="xs:string" minOccurs="0"/>
+ <xs:element name="Senders" type="t:ArrayOfSmtpAddressType" minOccurs="0"/>
+ <xs:element name="Recipients" type="t:ArrayOfSmtpAddressType" minOccurs="0"/>
+ <xs:element name="FromDate" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="ToDate" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="MessageTypes" type="t:ArrayOfSearchItemKindsType" minOccurs="0"/>
+ <xs:element name="SearchDumpster" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="IncludePersonalArchive" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="IncludeUnsearchableItems" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindMailboxStatisticsByKeywords" type="m:FindMailboxStatisticsByKeywordsType"/>
+
+ <xs:complexType name="FindMailboxStatisticsByKeywordsResponseType">
+ <xs:annotation>
+ <xs:documentation>
+ Response type for the FindMailboxStatisticsByKeywords web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindMailboxStatisticsByKeywordsResponse" type="m:FindMailboxStatisticsByKeywordsResponseType"/>
+
+ <xs:complexType name="FindMailboxStatisticsByKeywordsResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the FindMailboxStatisticsByKeywords web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MailboxStatisticsSearchResult" type="t:MailboxStatisticsSearchResultType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- GetSearchableMailboxes web method and response -->
+ <xs:complexType name="GetSearchableMailboxesType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the GetSearchableMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchFilter" type="xs:string" minOccurs="0"/>
+ <xs:element name="ExpandGroupMembership" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetSearchableMailboxes" type="m:GetSearchableMailboxesType"/>
+
+ <xs:complexType name="GetSearchableMailboxesResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the GetSearchableMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="SearchableMailboxes" type="t:ArrayOfSearchableMailboxesType"/>
+ <xs:element name="FailedMailboxes" type="t:ArrayOfFailedSearchMailboxesType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetSearchableMailboxesResponse" type="m:GetSearchableMailboxesResponseMessageType"/>
+
+ <!-- SearchMailboxes web method and response -->
+ <xs:complexType name="SearchMailboxesType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the SearchMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchQueries" type="t:NonEmptyArrayOfMailboxQueriesType" minOccurs="1"/>
+ <xs:element name="ResultType" type="t:SearchResultType" minOccurs="1"/>
+ <xs:element name="PreviewItemResponseShape" type="t:PreviewItemResponseShapeType" minOccurs="0"/>
+ <xs:element name="SortBy" type="t:FieldOrderType" minOccurs="0"/>
+ <xs:element name="Language" type="xs:string" minOccurs="0"/>
+ <xs:element name="Deduplication" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="PageSize" type="xs:int" minOccurs="0"/>
+ <xs:element name="PageItemReference" type="xs:string" minOccurs="0"/>
+ <xs:element name="PageDirection" type="t:SearchPageDirectionType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SearchMailboxes" type="m:SearchMailboxesType"/>
+
+ <xs:complexType name="SearchMailboxesResponseType">
+ <xs:annotation>
+ <xs:documentation>
+ Response type for the SearchMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SearchMailboxesResponse" type="m:SearchMailboxesResponseType"/>
+
+ <xs:complexType name="SearchMailboxesResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the SearchMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="SearchMailboxesResult" type="t:SearchMailboxesResultType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- GetDiscoverySearchConfiguration web method and response -->
+ <xs:complexType name="GetDiscoverySearchConfigurationType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the GetDiscoverySearchConfiguration web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchId" type="xs:string" minOccurs="0"/>
+ <xs:element name="ExpandGroupMembership" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="InPlaceHoldConfigurationOnly" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetDiscoverySearchConfiguration" type="m:GetDiscoverySearchConfigurationType"/>
+
+ <xs:complexType name="GetDiscoverySearchConfigurationResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the GetDiscoverySearchConfiguration web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="DiscoverySearchConfigurations" type="t:ArrayOfDiscoverySearchConfigurationType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetDiscoverySearchConfigurationResponse" type="m:GetDiscoverySearchConfigurationResponseMessageType"/>
+
+ <!-- GetHoldOnMailboxes web method and response -->
+ <xs:complexType name="GetHoldOnMailboxesType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the GetHoldOnMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="HoldId" type="xs:string" minOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetHoldOnMailboxes" type="m:GetHoldOnMailboxesType"/>
+
+ <xs:complexType name="GetHoldOnMailboxesResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the GetHoldOnMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MailboxHoldResult" type="t:MailboxHoldResultType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetHoldOnMailboxesResponse" type="m:GetHoldOnMailboxesResponseMessageType"/>
+
+ <!-- SetHoldOnMailboxes web method and response -->
+ <xs:complexType name="SetHoldOnMailboxesType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the SetHoldOnMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ActionType" type="t:HoldActionType" minOccurs="1"/>
+ <xs:element name="HoldId" type="xs:string" minOccurs="1"/>
+ <xs:element name="Query" type="xs:string" minOccurs="1"/>
+ <xs:element name="Mailboxes" type="t:ArrayOfStringsType" minOccurs="0"/>
+ <xs:element name="Language" type="xs:string" minOccurs="0"/>
+ <xs:element name="IncludeNonIndexableItems" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="Deduplication" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="InPlaceHoldIdentity" type="xs:string" minOccurs="0"/>
+ <xs:element name="ItemHoldPeriod" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SetHoldOnMailboxes" type="m:SetHoldOnMailboxesType"/>
+
+ <xs:complexType name="SetHoldOnMailboxesResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the SetHoldOnMailboxes web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MailboxHoldResult" type="t:MailboxHoldResultType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetHoldOnMailboxesResponse" type="m:SetHoldOnMailboxesResponseMessageType"/>
+
+ <!-- GetNonIndexableItemStatistics web method and response -->
+ <xs:complexType name="GetNonIndexableItemStatisticsType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the GetNonIndexableItemStatistics web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Mailboxes" type="t:NonEmptyArrayOfLegacyDNsType" minOccurs="1"/>
+ <xs:element name="SearchArchiveOnly" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetNonIndexableItemStatistics" type="m:GetNonIndexableItemStatisticsType"/>
+
+ <xs:complexType name="GetNonIndexableItemStatisticsResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the GetNonIndexableItemStatistics web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="NonIndexableItemStatistics" type="t:ArrayOfNonIndexableItemStatisticsType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetNonIndexableItemStatisticsResponse" type="m:GetNonIndexableItemStatisticsResponseMessageType"/>
+
+ <!-- GetNonIndexableItemDetails web method and response -->
+ <xs:complexType name="GetNonIndexableItemDetailsType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the GetNonIndexableItemDetails web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Mailboxes" type="t:NonEmptyArrayOfLegacyDNsType" minOccurs="1"/>
+ <xs:element name="PageSize" type="xs:int" minOccurs="0"/>
+ <xs:element name="PageItemReference" type="xs:string" minOccurs="0"/>
+ <xs:element name="PageDirection" type="t:SearchPageDirectionType" minOccurs="0"/>
+ <xs:element name="SearchArchiveOnly" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetNonIndexableItemDetails" type="m:GetNonIndexableItemDetailsType"/>
+
+ <xs:complexType name="GetNonIndexableItemDetailsResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the GetNonIndexableItemDetails web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="NonIndexableItemDetailsResult" type="t:NonIndexableItemDetailResultType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetNonIndexableItemDetailsResponse" type="m:GetNonIndexableItemDetailsResponseMessageType"/>
+
+ <!-- MarkAllItemsAsRead request -->
+ <xs:complexType name="MarkAllItemsAsReadType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ReadFlag" type="xs:boolean" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SuppressReadReceipts" type="xs:boolean" minOccurs="1" maxOccurs="1" />
+ <xs:element name="FolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="MarkAllItemsAsRead" type="m:MarkAllItemsAsReadType"/>
+
+ <!-- MarkAllItemsAsRead response -->
+ <xs:complexType name="MarkAllItemsAsReadResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="MarkAllItemsAsReadResponse" type="m:MarkAllItemsAsReadResponseType"/>
+
+ <!-- GetConversationItems request -->
+ <xs:complexType name="GetConversationItemsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemShape" type="t:ItemResponseShapeType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="FoldersToIgnore" type="t:NonEmptyArrayOfBaseFolderIdsType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MaxItemsToReturn" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SortOrder" type="t:ConversationNodeSortOrder" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MailboxScope" type="t:MailboxSearchLocationType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Conversations" type="t:ArrayOfConversationRequestsType" minOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetConversationItems" type="m:GetConversationItemsType"/>
+
+ <!-- GetConversationItems response -->
+ <xs:complexType name="GetConversationItemsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Conversation" type="t:ConversationResponseType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="GetConversationItemsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetConversationItemsResponse" type="m:GetConversationItemsResponseType"/>
+
+ <!-- GetOMEConfiguration request -->
+ <xs:complexType name="GetOMEConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetOMEConfiguration" type="m:GetOMEConfigurationType" />
+
+ <!-- GetOMEConfiguration response -->
+ <xs:complexType name="OMEConfigurationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Xml" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetOMEConfigurationResponse" type="m:OMEConfigurationResponseType"/>
+
+ <!-- SetOMEConfiguration request -->
+ <xs:complexType name="SetOMEConfigurationType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Xml" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetOMEConfiguration" type="m:SetOMEConfigurationType"/>
+
+ <!-- SetOMEConfiguration response -->
+ <xs:complexType name="SetOMEConfigurationResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetOMEConfigurationResponse" type="m:SetOMEConfigurationResponseType"/>
+
+ <!-- GetAppManifests request -->
+ <xs:complexType name="GetAppManifestsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ApiVersionSupported" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SchemaVersionSupported" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IncludeAllInstalledAddIns" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IncludeEntitlementData" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IncludeManifestData" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IncludeCustomAppsData" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ExtensionIds" type="m:ListOfExtensionIdsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="AddIns" type="m:ArrayOfPrivateCatalogAddInsType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="ListOfExtensionIdsType">
+ <xs:list itemType="t:GuidType" />
+ </xs:simpleType>
+
+ <xs:element name="GetAppManifests" type="m:GetAppManifestsType"/>
+
+ <!-- GetAppManifests response -->
+ <xs:complexType name="GetAppManifestsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:choice>
+ <xs:element name="Apps" type="t:ArrayOfAppsType" maxOccurs="1"/>
+ <xs:element name="Manifests" type="m:ArrayOfAppManifestsType" maxOccurs="1"/>
+ </xs:choice>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfAppManifestsType">
+ <xs:sequence>
+ <xs:element name="Manifest" type="xs:base64Binary" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="GetAppManifestsResponse" type="m:GetAppManifestsResponseType"/>
+
+ <!-- GetAppMarketplaceUrl request -->
+ <xs:complexType name="GetAppMarketplaceUrlType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetAppMarketplaceUrl" type="m:GetAppMarketplaceUrlType"/>
+
+ <!-- GetAppMarketplaceUrl response -->
+ <xs:complexType name="GetAppMarketplaceUrlResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="AppMarketplaceUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ConnectorsManagementUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetAppMarketplaceUrlResponse" type="m:GetAppMarketplaceUrlResponseMessageType"/>
+
+ <!-- MarkAsJunk request -->
+ <xs:complexType name="MarkAsJunkType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="IsJunk" type="xs:boolean" use="required" />
+ <xs:attribute name="MoveItem" type="xs:boolean" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="MarkAsJunk" type="m:MarkAsJunkType" />
+
+ <!-- MarkAsJunk response -->
+ <xs:complexType name="MarkAsJunkResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="MarkAsJunkResponse" type="m:MarkAsJunkResponseType" />
+
+ <xs:complexType name="MarkAsJunkResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:sequence>
+ <xs:element name="MovedItemId" type="t:ItemIdType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- ReportMessage request -->
+ <xs:complexType name="ReportMessageType">
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="ReportAction" type="t:ReportMessageActionType" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ReportMessage" type="m:ReportMessageType" />
+
+ <!-- ReportMessage response -->
+ <xs:complexType name="ReportMessageResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ReportMessageResponse" type="m:ReportMessageResponseType" />
+
+ <xs:complexType name="ReportMessageResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:sequence>
+ <xs:element name="MovedItemId" type="t:ItemIdType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- InstallApp request -->
+ <xs:complexType name="InstallAppType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Manifest" type="xs:base64Binary" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="MarketplaceAssetId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MarketplaceContentMarket" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SendWelcomeEmail" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ManifestUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="InstallApp" type="m:InstallAppType"/>
+
+ <!-- InstallApp response -->
+ <xs:complexType name="InstallAppResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="WasFirstInstall" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Extension" type="t:InstalledAppType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="InstallAppResponse" type="m:InstallAppResponseType"/>
+
+ <!-- UninstallApp request -->
+ <xs:complexType name="UninstallAppType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ID" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UninstallApp" type="m:UninstallAppType"/>
+
+ <!-- UninstallApp response -->
+ <xs:complexType name="UninstallAppResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="UninstallAppResponse" type="m:UninstallAppResponseType"/>
+
+ <!-- DisableApp request -->
+ <xs:complexType name="DisableAppType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ID" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="DisableReason" type="t:DisableReasonType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DisableApp" type="m:DisableAppType"/>
+
+ <!-- DisableApp response -->
+ <xs:complexType name="DisableAppResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DisableAppResponse" type="m:DisableAppResponseType"/>
+
+ <!-- AddNewImContactToGroup request -->
+ <xs:complexType name="AddNewImContactToGroupType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ImAddress" type="t:NonEmptyStringType"/>
+ <xs:element name="DisplayName" type="t:NonEmptyStringType" minOccurs="0"/>
+ <xs:element name="GroupId" type="t:ItemIdType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddNewImContactToGroup" type="m:AddNewImContactToGroupType"/>
+
+ <!-- AddNewImContactToGroup response-->
+ <xs:complexType name="AddNewImContactToGroupResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Persona" type="t:PersonaType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddNewImContactToGroupResponse" type="m:AddNewImContactToGroupResponseMessageType"/>
+
+ <!-- AddNewTelUriContactToGroup request -->
+ <xs:complexType name="AddNewTelUriContactToGroupType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="TelUriAddress" type="t:NonEmptyStringType"/>
+ <xs:element name="ImContactSipUriAddress" type="t:NonEmptyStringType"/>
+ <xs:element name="ImTelephoneNumber" type="t:NonEmptyStringType"/>
+ <xs:element name="GroupId" type="t:ItemIdType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddNewTelUriContactToGroup" type="m:AddNewTelUriContactToGroupType"/>
+
+ <!-- AddNewTelUriContactToGroup response-->
+ <xs:complexType name="AddNewTelUriContactToGroupResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Persona" type="t:PersonaType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddNewTelUriContactToGroupResponse" type="m:AddNewTelUriContactToGroupResponseMessageType"/>
+
+ <!-- AddImContactToGroup request -->
+ <xs:complexType name="AddImContactToGroupType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ContactId" type="t:ItemIdType"/>
+ <xs:element name="GroupId" type="t:ItemIdType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddImContactToGroup" type="m:AddImContactToGroupType"/>
+
+ <!-- AddImContactToGroup response-->
+ <xs:complexType name="AddImContactToGroupResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddImContactToGroupResponse" type="m:AddImContactToGroupResponseMessageType"/>
+
+ <!-- RemoveImContactFromGroup request -->
+ <xs:complexType name="RemoveImContactFromGroupType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ContactId" type="t:ItemIdType"/>
+ <xs:element name="GroupId" type="t:ItemIdType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveImContactFromGroup" type="m:RemoveImContactFromGroupType"/>
+
+ <!-- RemoveImContactFromGroup response-->
+ <xs:complexType name="RemoveImContactFromGroupResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveImContactFromGroupResponse" type="m:RemoveImContactFromGroupResponseMessageType"/>
+
+ <!-- AddImGroup request -->
+ <xs:complexType name="AddImGroupType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="DisplayName" type="t:NonEmptyStringType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddImGroup" type="m:AddImGroupType"/>
+
+ <!-- AddImGroup response-->
+ <xs:complexType name="AddImGroupResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ImGroup" type="t:ImGroupType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddImGroupResponse" type="m:AddImGroupResponseMessageType"/>
+
+ <!-- AddDistributionGroupToImList request -->
+ <xs:complexType name="AddDistributionGroupToImListType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SmtpAddress" type="t:NonEmptyStringType"/>
+ <xs:element name="DisplayName" type="t:NonEmptyStringType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddDistributionGroupToImList" type="m:AddDistributionGroupToImListType"/>
+
+ <!-- AddDistributionGroupToImList response-->
+ <xs:complexType name="AddDistributionGroupToImListResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ImGroup" type="t:ImGroupType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="AddDistributionGroupToImListResponse" type="m:AddDistributionGroupToImListResponseMessageType"/>
+
+ <!-- GetImItemList request -->
+ <xs:complexType name="GetImItemListType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ExtendedProperties" type="t:NonEmptyArrayOfExtendedFieldURIs" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetImItemList" type="m:GetImItemListType"/>
+
+ <!-- GetImItemList response-->
+ <xs:complexType name="GetImItemListResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ImItemList" type="t:ImItemListType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetImItemListResponse" type="m:GetImItemListResponseMessageType"/>
+
+ <!-- GetImItems request -->
+ <xs:complexType name="GetImItemsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ContactIds" type="t:NonEmptyArrayOfBaseItemIdsType" minOccurs="0"/>
+ <xs:element name="GroupIds" type="t:NonEmptyArrayOfBaseItemIdsType" minOccurs="0"/>
+ <xs:element name="ExtendedProperties" type="t:NonEmptyArrayOfExtendedFieldURIs" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetImItems" type="m:GetImItemsType"/>
+
+ <!-- GetImItems response-->
+ <xs:complexType name="GetImItemsResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="ImItemList" type="t:ImItemListType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetImItemsResponse" type="m:GetImItemsResponseMessageType"/>
+
+ <!-- RemoveContactFromImList request -->
+ <xs:complexType name="RemoveContactFromImListType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ContactId" type="t:ItemIdType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveContactFromImList" type="m:RemoveContactFromImListType"/>
+
+ <!-- RemoveContactFromImList response-->
+ <xs:complexType name="RemoveContactFromImListResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveContactFromImListResponse" type="m:RemoveContactFromImListResponseMessageType"/>
+
+ <!-- RemoveDistributionGroupFromImList request -->
+ <xs:complexType name="RemoveDistributionGroupFromImListType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="GroupId" type="t:ItemIdType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveDistributionGroupFromImList" type="m:RemoveDistributionGroupFromImListType"/>
+
+ <!-- RemoveDistributionGroupFromImList response-->
+ <xs:complexType name="RemoveDistributionGroupFromImListResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveDistributionGroupFromImListResponse" type="m:RemoveDistributionGroupFromImListResponseMessageType"/>
+
+ <!-- RemoveImGroup request -->
+ <xs:complexType name="RemoveImGroupType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="GroupId" type="t:ItemIdType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveImGroup" type="m:RemoveImGroupType"/>
+
+ <!-- RemoveImGroup response-->
+ <xs:complexType name="RemoveImGroupResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="RemoveImGroupResponse" type="m:RemoveImGroupResponseMessageType"/>
+
+ <!-- SetImGroup request -->
+ <xs:complexType name="SetImGroupType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="GroupId" type="t:ItemIdType"/>
+ <xs:element name="NewDisplayName" type="t:NonEmptyStringType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetImGroup" type="m:SetImGroupType"/>
+
+ <!-- SetImGroup response-->
+ <xs:complexType name="SetImGroupResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetImGroupResponse" type="m:SetImGroupResponseMessageType"/>
+
+ <!-- SetImListMigrationCompleted request -->
+ <xs:complexType name="SetImListMigrationCompletedType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ImListMigrationCompleted" type="xs:boolean"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetImListMigrationCompleted" type="m:SetImListMigrationCompletedType"/>
+
+ <!-- SetImListMigrationCompleted response-->
+ <xs:complexType name="SetImListMigrationCompletedResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="SetImListMigrationCompletedResponse" type="m:SetImListMigrationCompletedResponseMessageType"/>
+
+ <!-- GetUserRetentionPolicyTags web method and response -->
+ <xs:complexType name="GetUserRetentionPolicyTagsType">
+ <xs:annotation>
+ <xs:documentation>
+ Request type for the GetUserRetentionPolicyTags web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent mixed="false">
+ <xs:extension base="m:BaseRequestType" />
+ <!-- We Don't Need Input For GetUserRetentionPolicyTags. -->
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetUserRetentionPolicyTags" type="m:GetUserRetentionPolicyTagsType" />
+
+ <xs:complexType name="GetUserRetentionPolicyTagsResponseMessageType">
+ <xs:annotation>
+ <xs:documentation>
+ Response message type for the GetUserRetentionPolicyTags web method.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="RetentionPolicyTags" type="t:ArrayOfRetentionPolicyTagsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetUserRetentionPolicyTagsResponse" type="m:GetUserRetentionPolicyTagsResponseMessageType"/>
+
+ <!-- GetUserPhoto request -->
+ <xs:complexType name="GetUserPhotoType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Email" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SizeRequested" type="t:UserPhotoSizeType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="TypeRequested" type="t:UserPhotoTypeType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetUserPhoto" type="m:GetUserPhotoType"/>
+
+ <!-- GetUserPhoto response -->
+ <xs:complexType name="GetUserPhotoResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="HasChanged" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="PictureData" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="GetUserPhotoResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetUserPhotoResponse" type="m:GetUserPhotoResponseMessageType"/>
+
+ <xs:complexType name="GetMeetingSpaceType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetMeetingSpace" type="m:GetMeetingSpaceType"/>
+
+ <xs:complexType name="GetMeetingSpaceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingSpace" type="t:MeetingSpaceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetMeetingSpaceResponseMessage" type="m:GetMeetingSpaceResponseMessageType"/>
+
+ <xs:complexType name="CreateMeetingSpaceType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="MeetingSpace" type="t:MeetingSpaceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="CreateMeetingSpace" type="m:CreateMeetingSpaceType"/>
+
+ <xs:complexType name="CreateMeetingSpaceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingSpace" type="t:MeetingSpaceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="CreateMeetingSpaceResponseMessage" type="m:CreateMeetingSpaceResponseMessageType"/>
+
+ <xs:complexType name="UpdateMeetingSpaceType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="MeetingSpace" type="t:MeetingSpaceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateMeetingSpace" type="m:UpdateMeetingSpaceType"/>
+
+ <xs:complexType name="UpdateMeetingSpaceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingSpace" type="t:MeetingSpaceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateMeetingSpaceResponseMessage" type="m:UpdateMeetingSpaceResponseMessageType"/>
+
+ <xs:complexType name="FindMeetingSpaceByJoinUrlType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="JoinUrl" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindMeetingSpaceByJoinUrl" type="m:FindMeetingSpaceByJoinUrlType"/>
+
+ <xs:complexType name="FindMeetingSpaceByJoinUrlResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingSpace" type="t:MeetingSpaceType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="FindMeetingSpaceByJoinUrlResponseMessage" type="m:FindMeetingSpaceByJoinUrlResponseMessageType"/>
+
+ <xs:complexType name="DeleteMeetingSpaceType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DeleteMeetingSpace" type="m:DeleteMeetingSpaceType"/>
+
+ <xs:complexType name="DeleteMeetingSpaceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DeleteMeetingSpaceResponseMessage" type="m:DeleteMeetingSpaceResponseMessageType"/>
+
+ <xs:complexType name="GetMeetingInstanceRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetMeetingInstanceRequest" type="m:GetMeetingInstanceRequestType"/>
+
+ <xs:complexType name="GetMeetingInstanceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingInstance" type="t:MeetingInstanceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetMeetingInstanceResponse" type="m:GetMeetingInstanceResponseMessageType"/>
+
+ <xs:complexType name="CreateMeetingInstanceRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="MeetingInstance" type="t:MeetingInstanceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="CreateMeetingInstanceRequest" type="m:CreateMeetingInstanceRequestType"/>
+
+ <xs:complexType name="CreateMeetingInstanceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingInstance" type="t:MeetingInstanceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="CreateMeetingInstanceResponse" type="m:CreateMeetingInstanceResponseMessageType"/>
+
+ <xs:complexType name="UpdateMeetingInstanceRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="MeetingInstance" type="t:MeetingInstanceType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContentActivitiesToAdd" type="t:NonEmptyArrayOfContentActivities" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ParticipantActivitiesToAdd" type="t:NonEmptyArrayOfParticipantActivities" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateMeetingInstanceRequest" type="m:UpdateMeetingInstanceRequestType"/>
+
+ <xs:complexType name="UpdateMeetingInstanceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingInstance" type="t:MeetingInstanceType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="UpdateMeetingInstanceResponse" type="m:UpdateMeetingInstanceResponseMessageType"/>
+
+ <xs:complexType name="DeleteMeetingInstanceRequestType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DeleteMeetingInstanceRequest" type="m:DeleteMeetingInstanceRequestType"/>
+
+ <xs:complexType name="DeleteMeetingInstanceResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="DeleteMeetingInstanceResponse" type="m:DeleteMeetingInstanceResponseMessageType"/>
+
+ <!-- SetUserPhoto Request -->
+ <xs:complexType name="SetUserPhotoType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Email" type="t:NonEmptyStringType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Content" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="TypeRequested" type="t:UserPhotoTypeType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SetUserPhoto" type="m:SetUserPhotoType"/>
+
+ <!-- SetUserPhoto Response -->
+ <xs:complexType name="SetUserPhotoResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="SetUserPhotoResponse" type="m:SetUserPhotoResponseMessageType"/>
+
+ <!-- RegisterConsent Request -->
+ <xs:complexType name="RegisterConsentType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ConsentState" type="t:ConsentStateType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="RegisterConsent" type="m:RegisterConsentType"/>
+
+ <!-- RegisterConsent Response -->
+ <xs:complexType name="RegisterConsentResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="RegisterConsentResponse" type="m:RegisterConsentResponseMessageType"/>
+
+ <!-- FindAvailableMeetingTimes Request -->
+ <xs:complexType name="FindAvailableMeetingTimesType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Attendees" type="t:ArrayOfSmtpAddressType" minOccurs="0" />
+ <xs:element name="SearchWindowStart" type="xs:dateTime"/>
+ <xs:element name="SearchWindowDuration" type="xs:duration"/>
+ <xs:element name="MeetingDurationInMinutes" type="xs:int" minOccurs="0" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" />
+ <xs:element name="MaxCandidates" type="xs:int" minOccurs="0" />
+ <xs:element name="ActivityDomain" type="t:ActivityDomainType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindAvailableMeetingTimes" type="m:FindAvailableMeetingTimesType"/>
+
+ <!-- FindAvailableMeetingTimes Response -->
+ <xs:complexType name="FindAvailableMeetingTimesResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingTimeCandidates" type="t:ArrayOfMeetingTimeCandidate" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="EmptySuggestionsHint" type="t:EmptySuggestionReason" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindAvailableMeetingTimesResponse" type="m:FindAvailableMeetingTimesResponseMessageType"/>
+
+ <!-- FindMeetingTimeCandidates Request -->
+ <xs:complexType name="FindMeetingTimeCandidatesType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="AttendeeConstraints" type="t:FindMeetingTimesAttendeeConstraints" minOccurs="0" />
+ <xs:element name="LocationConstraints" type="t:FindMeetingTimesLocationConstraints" minOccurs="0" />
+ <xs:element name="SearchConstraints" type="t:FindMeetingTimesSearchConstraints" minOccurs="0" />
+ <xs:element name="Constraints" type="t:FindMeetingTimesConstraints" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindMeetingTimeCandidates" type="m:FindMeetingTimeCandidatesType"/>
+
+ <!-- FindMeetingTimeCandidates Response -->
+ <xs:complexType name="FindMeetingTimeCandidatesResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="MeetingTimeCandidates" type="t:ArrayOfMeetingTimeCandidate" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="FindMeetingTimeCandidatesResponse" type="m:FindMeetingTimeCandidatesResponseMessageType"/>
+
+ <!-- Instant Search API v2.0 -->
+
+ <!-- Start Search Session -->
+ <xs:complexType name="StartSearchSession">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchSessionId" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="WarmupOptions" type="t:WarmupOptionsType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SuggestionTypes" type="t:SuggestionKindType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SearchScope" type="t:ArrayOfSearchScopeType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="IdFormat" type="t:IdFormatType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ApplicationId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Scenario" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="StartSearchSession" type="m:StartSearchSession"/>
+
+ <xs:complexType name="StartSearchSessionResponseMessage">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="StartSearchSessionResponse" type="m:StartSearchSessionResponseMessage"/>
+
+ <!-- GetSearchSuggestions -->
+ <xs:complexType name="GetSearchSuggestions">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchSessionId" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Query" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SuggestionTypes" type="t:SuggestionKindType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SuggestionsPrimer" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MaxSuggestionsCountPerSuggestionType" type="xs:long" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SearchScope" type="t:ArrayOfSearchScopeType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Scenario" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetSearchSuggestions" type="m:GetSearchSuggestions"/>
+
+ <xs:complexType name="GetSearchSuggestionsResponseMessage">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="SearchSuggestions" type="t:SearchSuggestionsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="GetSearchSuggestionsResponse" type="m:GetSearchSuggestionsResponseMessage"/>
+
+ <!-- DeleteSearchSuggestion -->
+ <xs:complexType name="DeleteSearchSuggestion">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchSessionId" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Query" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SuggestionTypes" type="t:SuggestionKindType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SearchScope" type="t:ArrayOfSearchScopeType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Scenario" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteSearchSuggestion" type="m:DeleteSearchSuggestion"/>
+
+ <xs:complexType name="DeleteSearchSuggestionResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="Response" type="t:DeleteSearchSuggestionResponseType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="DeleteSearchSuggestionResponse" type="m:DeleteSearchSuggestionResponseMessageType"/>
+
+ <!-- ExecuteSearchRequest -->
+ <xs:complexType name="ExecuteSearch">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="ApplicationId" type="t:SearchApplicationIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Scenario" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SearchSessionId" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SearchScope" type="t:ArrayOfSearchScopeType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Query" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="AnalyzedQuery" type="t:AnalyzedQuery" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ResultRowCount" type="xs:long" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ResultRowOffset" type="xs:long" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MaxResultsCountHint" type="xs:long" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MaxPreviewLength" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SearchRefiners" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="SearchRefiner" type="t:DynamicRefinerQueryType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="ExtendedKeywords" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="ExtendedKeywordDefinition" type="t:ExtendedKeywordDefinitionType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="RetrieveRefiners" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MaxRefinersCountPerRefinerType" type="xs:long" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IdFormat" type="t:IdFormatType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ItemTypes" type="t:ItemTypesFilterType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="PropertySetName" type="t:SearchResultsPropertySetNameType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SearchRestrictions" type="t:RestrictionType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IncludeDeleted" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SortOrder" type="t:ExecuteSearchSortOrderType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="KeywordMatchOption" type="t:MatchOptionsType" default="Prefix" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ReturnAdditionalIds" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ExecuteSearch" type="m:ExecuteSearch"/>
+
+ <xs:complexType name="ExecuteSearchResponseMessage">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="SearchResults" type="t:SearchResultsType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="ExecuteSearchResponse" type="m:ExecuteSearchResponseMessage"/>
+
+ <!-- EndSearchSession -->
+ <xs:complexType name="EndSearchSession">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="SearchSessionId" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="EndSearchSession" type="m:EndSearchSession"/>
+
+ <xs:complexType name="EndSearchSessionResponseMessage">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="EndSearchSessionResponse" type="m:EndSearchSessionResponseMessage"/>
+
+ <!-- GetLastPrivateCatalogUpdate request -->
+ <xs:complexType name="GetLastPrivateCatalogUpdateType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Client" type="t:OfficeClientType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetLastPrivateCatalogUpdate" type="m:GetLastPrivateCatalogUpdateType"/>
+
+ <!-- GetLastPrivateCatalogUpdate response -->
+ <xs:complexType name="GetLastPrivateCatalogUpdateResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:choice maxOccurs="1" minOccurs="0">
+ <xs:element name="LastUpdate" type="xs:dateTime"/>
+ <xs:element name="CatalogHash" type="xs:string"/>
+ </xs:choice>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetLastPrivateCatalogUpdateResponse" type="m:GetLastPrivateCatalogUpdateResponseType"/>
+
+ <!-- GetPrivateCatalogAddIns request -->
+ <xs:complexType name="GetPrivateCatalogAddInsType">
+ <xs:complexContent>
+ <xs:extension base="m:BaseRequestType">
+ <xs:sequence>
+ <xs:element name="Client" type="t:OfficeClientType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="GetPrivateCatalogAddIns" type="m:GetPrivateCatalogAddInsType"/>
+
+ <!-- GetPrivateCatalogAddIns response -->
+ <xs:complexType name="GetPrivateCatalogAddInsResponseType">
+ <xs:complexContent>
+ <xs:extension base="m:ResponseMessageType">
+ <xs:sequence>
+ <xs:element name="AddIns" type="m:ArrayOfPrivateCatalogAddInsType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPrivateCatalogAddInsType">
+ <xs:sequence>
+ <xs:element name="AddIn" type="m:PrivateCatalogAddInsType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PrivateCatalogAddInsType">
+ <xs:attribute name="ProductId" type="xs:string" use="required"/>
+ <xs:attribute name="State" type="t:AddInStateType" use="required"/>
+ <xs:attribute name="Version" type="t:VersionType" use="required"/>
+ </xs:complexType>
+
+ <xs:element name="GetPrivateCatalogAddInsResponse" type="m:GetPrivateCatalogAddInsResponseType"/>
+</xs:schema>
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/services.wsdl b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/services.wsdl
new file mode 100644
index 00000000..7461185f
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/services.wsdl
@@ -0,0 +1,3624 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:tns="http://schemas.microsoft.com/exchange/services/2006/messages"
+ xmlns:s="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://schemas.microsoft.com/exchange/services/2006/messages"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
+ <wsdl:types>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import namespace="http://schemas.microsoft.com/exchange/services/2006/messages" schemaLocation="messages.xsd"/>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="FindAvailableMeetingTimesSoapIn">
+ <wsdl:part name="request" element="tns:FindAvailableMeetingTimes"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="FindAvailableMeetingTimesSoapOut">
+ <wsdl:part name="FindAvailableMeetingTimesResult" element="tns:FindAvailableMeetingTimesResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="FindMeetingTimeCandidatesSoapIn">
+ <wsdl:part name="request" element="tns:FindMeetingTimeCandidates"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="FindMeetingTimeCandidatesSoapOut">
+ <wsdl:part name="FindMeetingTimeCandidatesResult" element="tns:FindMeetingTimeCandidatesResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="UploadItemsSoapIn">
+ <wsdl:part name="request" element="tns:UploadItems"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="UploadItemsSoapOut">
+ <wsdl:part name="UploadItemsResult" element="tns:UploadItemsResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="ExportItemsSoapIn">
+ <wsdl:part name="request" element="tns:ExportItems"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="ExportItemsSoapOut">
+ <wsdl:part name="ExportItemsResult" element="tns:ExportItemsResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="ConvertIdSoapIn">
+ <wsdl:part name="request" element="tns:ConvertId"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="ConvertIdSoapOut">
+ <wsdl:part name="ConvertIdResult" element="tns:ConvertIdResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetFolderSoapIn">
+ <wsdl:part name="request" element="tns:GetFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetFolderSoapOut">
+ <wsdl:part name="GetFolderResult" element="tns:GetFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CreateFolderSoapIn">
+ <wsdl:part name="request" element="tns:CreateFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="CreateFolderSoapOut">
+ <wsdl:part name="CreateFolderResult" element="tns:CreateFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CreateFolderPathSoapIn">
+ <wsdl:part name="request" element="tns:CreateFolderPath" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="CreateFolderPathSoapOut">
+ <wsdl:part name="CreateFolderPathResult" element="tns:CreateFolderPathResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CreateManagedFolderSoapIn">
+ <wsdl:part name="request" element="tns:CreateManagedFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="CreateManagedFolderSoapOut">
+ <wsdl:part name="CreateManagedFolderResult" element="tns:CreateManagedFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteFolderSoapIn">
+ <wsdl:part name="request" element="tns:DeleteFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteFolderSoapOut">
+ <wsdl:part name="DeleteFolderResult" element="tns:DeleteFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="EmptyFolderSoapIn">
+ <wsdl:part name="request" element="tns:EmptyFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="EmptyFolderSoapOut">
+ <wsdl:part name="EmptyFolderResult" element="tns:EmptyFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateFolderSoapIn">
+ <wsdl:part name="request" element="tns:UpdateFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateFolderSoapOut">
+ <wsdl:part name="UpdateFolderResult" element="tns:UpdateFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="MoveFolderSoapIn">
+ <wsdl:part name="request" element="tns:MoveFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="MoveFolderSoapOut">
+ <wsdl:part name="MoveFolderResult" element="tns:MoveFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CopyFolderSoapIn">
+ <wsdl:part name="request" element="tns:CopyFolder" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="CopyFolderSoapOut">
+ <wsdl:part name="CopyFolderResult" element="tns:CopyFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="FindFolderSoapIn">
+ <wsdl:part name="request" element="tns:FindFolder"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="FindFolderSoapOut">
+ <wsdl:part name="FindFolderResult" element="tns:FindFolderResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetItemSoapIn">
+ <wsdl:part name="request" element="tns:GetItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ <wsdl:part name="DateTimePrecision" element="t:DateTimePrecision" />
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetItemSoapOut">
+ <wsdl:part name="GetItemResult" element="tns:GetItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CreateItemSoapIn">
+ <wsdl:part name="request" element="tns:CreateItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="CreateItemSoapOut">
+ <wsdl:part name="CreateItemResult" element="tns:CreateItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteItemSoapIn">
+ <wsdl:part name="request" element="tns:DeleteItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteItemSoapOut">
+ <wsdl:part name="DeleteItemResult" element="tns:DeleteItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateItemSoapIn">
+ <wsdl:part name="request" element="tns:UpdateItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateItemSoapOut">
+ <wsdl:part name="UpdateItemResult" element="tns:UpdateItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateItemInRecoverableItemsSoapIn">
+ <wsdl:part name="request" element="tns:UpdateItemInRecoverableItems" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateItemInRecoverableItemsSoapOut">
+ <wsdl:part name="UpdateItemInRecoverableItemsResult" element="tns:UpdateItemInRecoverableItemsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="SendItemSoapIn">
+ <wsdl:part name="request" element="tns:SendItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SendItemSoapOut">
+ <wsdl:part name="SendItemResult" element="tns:SendItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="MoveItemSoapIn">
+ <wsdl:part name="request" element="tns:MoveItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="MoveItemSoapOut">
+ <wsdl:part name="MoveItemResult" element="tns:MoveItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CopyItemSoapIn">
+ <wsdl:part name="request" element="tns:CopyItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="CopyItemSoapOut">
+ <wsdl:part name="CopyItemResult" element="tns:CopyItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="ArchiveItemSoapIn">
+ <wsdl:part name="request" element="tns:ArchiveItem" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="ArchiveItemSoapOut">
+ <wsdl:part name="ArchiveItemResult" element="tns:ArchiveItemResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CreateAttachmentSoapIn">
+ <wsdl:part name="request" element="tns:CreateAttachment" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="CreateAttachmentSoapOut">
+ <wsdl:part name="CreateAttachmentResult" element="tns:CreateAttachmentResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteAttachmentSoapIn">
+ <wsdl:part name="request" element="tns:DeleteAttachment" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteAttachmentSoapOut">
+ <wsdl:part name="DeleteAttachmentResult" element="tns:DeleteAttachmentResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetAttachmentSoapIn">
+ <wsdl:part name="request" element="tns:GetAttachment" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ </wsdl:message>
+ <wsdl:message name="GetAttachmentSoapOut">
+ <wsdl:part name="GetAttachmentResult" element="tns:GetAttachmentResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetClientAccessTokenSoapIn">
+ <wsdl:part name="request" element="tns:GetClientAccessToken" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetClientAccessTokenSoapOut">
+ <wsdl:part name="GetClientAccessTokenResult" element="tns:GetClientAccessTokenResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetFocusedOtherOverridesSoapIn">
+ <wsdl:part name="request" element="tns:GetFocusedOtherOverrides"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetFocusedOtherOverridesSoapOut">
+ <wsdl:part name="GetFocusedOtherOverridesResult" element="tns:GetFocusedOtherOverridesResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="CreateOrUpdateFocusedOtherOverrideSoapIn">
+ <wsdl:part name="request" element="tns:CreateOrUpdateFocusedOtherOverride"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="CreateOrUpdateFocusedOtherOverrideSoapOut">
+ <wsdl:part name="CreateOrUpdateFocusedOtherOverrideResult" element="tns:CreateOrUpdateFocusedOtherOverrideResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteFocusedOtherOverrideSoapIn">
+ <wsdl:part name="request" element="tns:DeleteFocusedOtherOverride"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteFocusedOtherOverrideSoapOut">
+ <wsdl:part name="DeleteFocusedOtherOverrideResult" element="tns:DeleteFocusedOtherOverrideResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="ResolveNamesSoapIn">
+ <wsdl:part name="request" element="tns:ResolveNames" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="ResolveNamesSoapOut">
+ <wsdl:part name="ResolveNamesResult" element="tns:ResolveNamesResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="ExpandDLSoapIn">
+ <wsdl:part name="request" element="tns:ExpandDL" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="ExpandDLSoapOut">
+ <wsdl:part name="ExpandDLResult" element="tns:ExpandDLResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetServerTimeZonesSoapIn">
+ <wsdl:part name="request" element="tns:GetServerTimeZones" />
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetServerTimeZonesSoapOut">
+ <wsdl:part name="GetServerTimeZonesResult" element="tns:GetServerTimeZonesResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="FindItemSoapIn">
+ <wsdl:part name="request" element="tns:FindItem"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext"/>
+ <wsdl:part name="DateTimePrecision" element="t:DateTimePrecision" />
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="FindItemSoapOut">
+ <wsdl:part name="FindItemResult" element="tns:FindItemResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="SubscribeSoapIn">
+ <wsdl:part name="request" element="tns:Subscribe" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SubscribeSoapOut">
+ <wsdl:part name="SubscribeResult" element="tns:SubscribeResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="UnsubscribeSoapIn">
+ <wsdl:part name="request" element="tns:Unsubscribe" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="UnsubscribeSoapOut">
+ <wsdl:part name="UnsubscribeResult" element="tns:UnsubscribeResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetEventsSoapIn">
+ <wsdl:part name="request" element="tns:GetEvents" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetEventsSoapOut">
+ <wsdl:part name="GetEventsResult" element="tns:GetEventsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetStreamingEventsSoapIn">
+ <wsdl:part name="request" element="tns:GetStreamingEvents" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetStreamingEventsSoapOut">
+ <wsdl:part name="GetStreamingEventsResult" element="tns:GetStreamingEventsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="SyncFolderHierarchySoapIn">
+ <wsdl:part name="request" element="tns:SyncFolderHierarchy" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SyncFolderHierarchySoapOut">
+ <wsdl:part name="SyncFolderHierarchyResult" element="tns:SyncFolderHierarchyResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="SyncFolderItemsSoapIn">
+ <wsdl:part name="request" element="tns:SyncFolderItems" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SyncFolderItemsSoapOut">
+ <wsdl:part name="SyncFolderItemsResult" element="tns:SyncFolderItemsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetDelegateSoapIn">
+ <wsdl:part name="request" element="tns:GetDelegate" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetDelegateSoapOut">
+ <wsdl:part name="GetDelegateResult" element="tns:GetDelegateResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="AddDelegateSoapIn">
+ <wsdl:part name="request" element="tns:AddDelegate" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="AddDelegateSoapOut">
+ <wsdl:part name="AddDelegateResult" element="tns:AddDelegateResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="RemoveDelegateSoapIn">
+ <wsdl:part name="request" element="tns:RemoveDelegate" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="RemoveDelegateSoapOut">
+ <wsdl:part name="RemoveDelegateResult" element="tns:RemoveDelegateResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateDelegateSoapIn">
+ <wsdl:part name="request" element="tns:UpdateDelegate" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateDelegateSoapOut">
+ <wsdl:part name="UpdateDelegateResult" element="tns:UpdateDelegateResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="CreateUserConfigurationSoapIn">
+ <wsdl:part name="request" element="tns:CreateUserConfiguration" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="CreateUserConfigurationSoapOut">
+ <wsdl:part name="CreateUserConfigurationResult" element="tns:CreateUserConfigurationResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteUserConfigurationSoapIn">
+ <wsdl:part name="request" element="tns:DeleteUserConfiguration" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteUserConfigurationSoapOut">
+ <wsdl:part name="DeleteUserConfigurationResult" element="tns:DeleteUserConfigurationResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetUserConfigurationSoapIn">
+ <wsdl:part name="request" element="tns:GetUserConfiguration" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetUserConfigurationSoapOut">
+ <wsdl:part name="GetUserConfigurationResult" element="tns:GetUserConfigurationResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetSpecificUserConfigurationSoapIn">
+ <wsdl:part name="request" element="tns:GetSpecificUserConfiguration" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetSpecificUserConfigurationSoapOut">
+ <wsdl:part name="GetSpecificUserConfigurationResult" element="tns:GetSpecificUserConfigurationResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateUserConfigurationSoapIn">
+ <wsdl:part name="request" element="tns:UpdateUserConfiguration" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateUserConfigurationSoapOut">
+ <wsdl:part name="UpdateUserConfigurationResult" element="tns:UpdateUserConfigurationResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Availability Service messages -->
+ <wsdl:message name="GetUserAvailabilitySoapIn">
+ <wsdl:part name="GetUserAvailabilityRequest" element="tns:GetUserAvailabilityRequest" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetUserAvailabilitySoapOut">
+ <wsdl:part name="GetUserAvailabilityResult" element="tns:GetUserAvailabilityResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetUserOofSettingsSoapIn">
+ <wsdl:part name="GetUserOofSettingsRequest" element="tns:GetUserOofSettingsRequest" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetUserOofSettingsSoapOut">
+ <wsdl:part name="GetUserOofSettingsResult" element="tns:GetUserOofSettingsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="SetUserOofSettingsSoapIn">
+ <wsdl:part name="SetUserOofSettingsRequest" element="tns:SetUserOofSettingsRequest" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SetUserOofSettingsSoapOut">
+ <wsdl:part name="SetUserOofSettingsResult" element="tns:SetUserOofSettingsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- MailTips Messages -->
+ <wsdl:message name="GetMailTipsSoapIn">
+ <wsdl:part name="request" element="tns:GetMailTips" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ </wsdl:message>
+ <wsdl:message name="GetMailTipsSoapOut">
+ <wsdl:part name="GetMailTipsResult" element="tns:GetMailTipsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- UM Messages -->
+ <wsdl:message name="PlayOnPhoneSoapIn">
+ <wsdl:part name="request" element="tns:PlayOnPhone"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="PlayOnPhoneSoapOut">
+ <wsdl:part name="PlayOnPhoneResult" element="tns:PlayOnPhoneResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetPhoneCallInformationSoapIn">
+ <wsdl:part name="request" element="tns:GetPhoneCallInformation"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetPhoneCallInformationSoapOut">
+ <wsdl:part name="GetPhoneCallInformationResult" element="tns:GetPhoneCallInformationResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="DisconnectPhoneCallSoapIn">
+ <wsdl:part name="request" element="tns:DisconnectPhoneCall"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DisconnectPhoneCallSoapOut">
+ <wsdl:part name="DisconnectPhoneCallResult" element="tns:DisconnectPhoneCallResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+
+ <!-- Sharing Messages -->
+ <wsdl:message name="GetSharingMetadataSoapIn">
+ <wsdl:part name="request" element="tns:GetSharingMetadata" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetSharingMetadataSoapOut">
+ <wsdl:part name="GetSharingMetadataResult" element="tns:GetSharingMetadataResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="RefreshSharingFolderSoapIn">
+ <wsdl:part name="request" element="tns:RefreshSharingFolder" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="RefreshSharingFolderSoapOut">
+ <wsdl:part name="RefreshSharingFolderResult" element="tns:RefreshSharingFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetSharingFolderSoapIn">
+ <wsdl:part name="request" element="tns:GetSharingFolder" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetSharingFolderSoapOut">
+ <wsdl:part name="GetSharingFolderResult" element="tns:GetSharingFolderResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- SetTeamMailbox -->
+ <wsdl:message name="SetTeamMailboxSoapIn">
+ <wsdl:part name="request" element="tns:SetTeamMailbox"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="SetTeamMailboxSoapOut">
+ <wsdl:part name="SetTeamMailboxResult" element="tns:SetTeamMailboxResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- UnpinTeamMailbox -->
+ <wsdl:message name="UnpinTeamMailboxSoapIn">
+ <wsdl:part name="request" element="tns:UnpinTeamMailbox"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="UnpinTeamMailboxSoapOut">
+ <wsdl:part name="UnpinTeamMailboxResult" element="tns:UnpinTeamMailboxResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Find A Room Service Messages -->
+
+ <!-- GetRoomLists Service Messages -->
+ <wsdl:message name="GetRoomListsSoapIn">
+ <wsdl:part name="GetRoomListsRequest" element="tns:GetRoomLists" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetRoomListsSoapOut">
+ <wsdl:part name="GetRoomListsResult" element="tns:GetRoomListsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- GetRooms Service Messages -->
+ <wsdl:message name="GetRoomsSoapIn">
+ <wsdl:part name="GetRoomsRequest" element="tns:GetRooms" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetRoomsSoapOut">
+ <wsdl:part name="GetRoomsResult" element="tns:GetRoomsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- GetServiceConfiguration Messages -->
+ <wsdl:message name="GetServiceConfigurationSoapIn">
+ <wsdl:part name="request" element="tns:GetServiceConfiguration" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ </wsdl:message>
+ <wsdl:message name="GetServiceConfigurationSoapOut">
+ <wsdl:part name="GetServiceConfigurationResult" element="tns:GetServiceConfigurationResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- MessageTracking Messages -->
+ <wsdl:message name="FindMessageTrackingReportSoapIn">
+ <wsdl:part name="request" element="tns:FindMessageTrackingReport"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="FindMessageTrackingReportSoapOut">
+ <wsdl:part name="FindMessageTrackingReportResult" element="tns:FindMessageTrackingReportResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetMessageTrackingReportSoapIn">
+ <wsdl:part name="request" element="tns:GetMessageTrackingReport"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetMessageTrackingReportSoapOut">
+ <wsdl:part name="GetMessageTrackingReportResult" element="tns:GetMessageTrackingReportResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Conversation Messages-->
+ <wsdl:message name="FindConversationSoapIn">
+ <wsdl:part name="request" element="tns:FindConversation" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="FindConversationSoapOut">
+ <wsdl:part name="FindConversationResult" element="tns:FindConversationResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <wsdl:message name="ApplyConversationActionSoapIn">
+ <wsdl:part name="request" element="tns:ApplyConversationAction" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="ApplyConversationActionSoapOut">
+ <wsdl:part name="ApplyConversationActionResult" element="tns:ApplyConversationActionResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <wsdl:message name="GetConversationItemsSoapIn">
+ <wsdl:part name="request" element="tns:GetConversationItems" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="GetConversationItemsSoapOut">
+ <wsdl:part name="GetConversationItemsResult" element="tns:GetConversationItemsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <!-- FindPeople Messages-->
+ <wsdl:message name="FindPeopleSoapIn">
+ <wsdl:part name="request" element="tns:FindPeople" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="FindPeopleSoapOut">
+ <wsdl:part name="FindPeopleResult" element="tns:FindPeopleResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <!-- FindTags Messages-->
+ <wsdl:message name="FindTagsSoapIn">
+ <wsdl:part name="request" element="tns:FindTags" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="FindTagsSoapOut">
+ <wsdl:part name="FindTagsResult" element="tns:FindTagsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <!-- AddTag Messages-->
+ <wsdl:message name="AddTagSoapIn">
+ <wsdl:part name="request" element="tns:AddTag" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="AddTagSoapOut">
+ <wsdl:part name="AddTagResult" element="tns:AddTagResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <!-- HideTag Messages-->
+ <wsdl:message name="HideTagSoapIn">
+ <wsdl:part name="request" element="tns:HideTag" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="HideTagSoapOut">
+ <wsdl:part name="HideTagResult" element="tns:HideTagResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <!-- GetPersona Messages-->
+ <wsdl:message name="GetPersonaSoapIn">
+ <wsdl:part name="request" element="tns:GetPersona" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ </wsdl:message>
+ <wsdl:message name="GetPersonaSoapOut">
+ <wsdl:part name="GetPersonaResult" element="tns:GetPersonaResponseMessage" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <!-- Inbox Rules Messages -->
+ <wsdl:message name="GetInboxRulesSoapIn">
+ <wsdl:part name="request" element="tns:GetInboxRules" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation" />
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext" />
+ </wsdl:message>
+ <wsdl:message name="GetInboxRulesSoapOut">
+ <wsdl:part name="GetInboxRulesResult" element="tns:GetInboxRulesResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <wsdl:message name="UpdateInboxRulesSoapIn">
+ <wsdl:part name="request" element="tns:UpdateInboxRules" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation" />
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion" />
+ <wsdl:part name="TimeZoneContext" element="t:TimeZoneContext" />
+ </wsdl:message>
+ <wsdl:message name="UpdateInboxRulesSoapOut">
+ <wsdl:part name="UpdateInboxRulesResult" element="tns:UpdateInboxRulesResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo" />
+ </wsdl:message>
+
+ <wsdl:message name="GetPasswordExpirationDateSoapIn">
+ <wsdl:part name="request" element="tns:GetPasswordExpirationDate" />
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetPasswordExpirationDateSoapOut">
+ <wsdl:part name="GetPasswordExpirationDateResult" element="tns:GetPasswordExpirationDateResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Mailbox Search Messages -->
+ <wsdl:message name="GetSearchableMailboxesSoapIn">
+ <wsdl:part name="request" element="tns:GetSearchableMailboxes"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetSearchableMailboxesSoapOut">
+ <wsdl:part name="GetSearchableMailboxesResult" element="tns:GetSearchableMailboxesResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="SearchMailboxesSoapIn">
+ <wsdl:part name="request" element="tns:SearchMailboxes"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="SearchMailboxesSoapOut">
+ <wsdl:part name="SearchMailboxesResult" element="tns:SearchMailboxesResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetDiscoverySearchConfigurationSoapIn">
+ <wsdl:part name="request" element="tns:GetDiscoverySearchConfiguration"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetDiscoverySearchConfigurationSoapOut">
+ <wsdl:part name="GetDiscoverySearchConfigurationResult" element="tns:GetDiscoverySearchConfigurationResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetHoldOnMailboxesSoapIn">
+ <wsdl:part name="request" element="tns:GetHoldOnMailboxes"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetHoldOnMailboxesSoapOut">
+ <wsdl:part name="GetHoldOnMailboxesResult" element="tns:GetHoldOnMailboxesResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="SetHoldOnMailboxesSoapIn">
+ <wsdl:part name="request" element="tns:SetHoldOnMailboxes"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="SetHoldOnMailboxesSoapOut">
+ <wsdl:part name="SetHoldOnMailboxesResult" element="tns:SetHoldOnMailboxesResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetNonIndexableItemStatisticsSoapIn">
+ <wsdl:part name="request" element="tns:GetNonIndexableItemStatistics"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetNonIndexableItemStatisticsSoapOut">
+ <wsdl:part name="GetNonIndexableItemStatisticsResult" element="tns:GetNonIndexableItemStatisticsResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+ <wsdl:message name="GetNonIndexableItemDetailsSoapIn">
+ <wsdl:part name="request" element="tns:GetNonIndexableItemDetails"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetNonIndexableItemDetailsSoapOut">
+ <wsdl:part name="GetNonIndexableItemDetailsResult" element="tns:GetNonIndexableItemDetailsResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="MarkAllItemsAsReadSoapIn">
+ <wsdl:part name="request" element="tns:MarkAllItemsAsRead" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="MarkAllItemsAsReadSoapOut">
+ <wsdl:part name="MarkAllItemsAsReadResult" element="tns:MarkAllItemsAsReadResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="MarkAsJunkSoapIn">
+ <wsdl:part name="request" element="tns:MarkAsJunk" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="MarkAsJunkSoapOut">
+ <wsdl:part name="MarkAsJunkResult" element="tns:MarkAsJunkResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="ReportMessageSoapIn">
+ <wsdl:part name="request" element="tns:ReportMessage" />
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="ReportMessageSoapOut">
+ <wsdl:part name="ReportMessageResult" element="tns:ReportMessageResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetAppManifestsSoapIn">
+ <wsdl:part name="request" element="tns:GetAppManifests" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetAppManifestsSoapOut">
+ <wsdl:part name="GetAppManifestsResult" element="tns:GetAppManifestsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="InstallAppSoapIn">
+ <wsdl:part name="request" element="tns:InstallApp" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="InstallAppSoapOut">
+ <wsdl:part name="InstallAppResult" element="tns:InstallAppResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="UninstallAppSoapIn">
+ <wsdl:part name="request" element="tns:UninstallApp" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="UninstallAppSoapOut">
+ <wsdl:part name="UninstallAppResult" element="tns:UninstallAppResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="DisableAppSoapIn">
+ <wsdl:part name="request" element="tns:DisableApp" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DisableAppSoapOut">
+ <wsdl:part name="DisableAppResult" element="tns:DisableAppResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- RegisterConsent Messages -->
+ <wsdl:message name="RegisterConsentSoapIn">
+ <wsdl:part name="request" element="tns:RegisterConsent"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="RegisterConsentSoapOut">
+ <wsdl:part name="RegisterConsentResult" element="tns:RegisterConsentResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetAppMarketplaceUrlSoapIn">
+ <wsdl:part name="request" element="tns:GetAppMarketplaceUrl" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetAppMarketplaceUrlSoapOut">
+ <wsdl:part name="GetAppMarketplaceUrlResult" element="tns:GetAppMarketplaceUrlResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Unified contact store Messages -->
+ <wsdl:message name="AddNewImContactToGroupSoapIn">
+ <wsdl:part name="request" element="tns:AddNewImContactToGroup"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="AddNewImContactToGroupSoapOut">
+ <wsdl:part name="AddNewImContactToGroupResult" element="tns:AddNewImContactToGroupResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="AddNewTelUriContactToGroupSoapIn">
+ <wsdl:part name="request" element="tns:AddNewTelUriContactToGroup"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="AddNewTelUriContactToGroupSoapOut">
+ <wsdl:part name="AddNewTelUriContactToGroupResult" element="tns:AddNewTelUriContactToGroupResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="AddImContactToGroupSoapIn">
+ <wsdl:part name="request" element="tns:AddImContactToGroup"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="AddImContactToGroupSoapOut">
+ <wsdl:part name="AddImContactToGroupResult" element="tns:AddImContactToGroupResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="RemoveImContactFromGroupSoapIn">
+ <wsdl:part name="request" element="tns:RemoveImContactFromGroup"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="RemoveImContactFromGroupSoapOut">
+ <wsdl:part name="RemoveImContactFromGroupResult" element="tns:RemoveImContactFromGroupResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="AddImGroupSoapIn">
+ <wsdl:part name="request" element="tns:AddImGroup"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="AddImGroupSoapOut">
+ <wsdl:part name="AddImGroupResult" element="tns:AddImGroupResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="AddDistributionGroupToImListSoapIn">
+ <wsdl:part name="request" element="tns:AddDistributionGroupToImList"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="AddDistributionGroupToImListSoapOut">
+ <wsdl:part name="AddDistributionGroupToImListResult" element="tns:AddDistributionGroupToImListResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetImItemListSoapIn">
+ <wsdl:part name="request" element="tns:GetImItemList"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetImItemListSoapOut">
+ <wsdl:part name="GetImItemListResult" element="tns:GetImItemListResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetImItemsSoapIn">
+ <wsdl:part name="request" element="tns:GetImItems"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetImItemsSoapOut">
+ <wsdl:part name="GetImItemsResult" element="tns:GetImItemsResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="RemoveContactFromImListSoapIn">
+ <wsdl:part name="request" element="tns:RemoveContactFromImList"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="RemoveContactFromImListSoapOut">
+ <wsdl:part name="RemoveContactFromImListResult" element="tns:RemoveContactFromImListResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="RemoveDistributionGroupFromImListSoapIn">
+ <wsdl:part name="request" element="tns:RemoveDistributionGroupFromImList"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="RemoveDistributionGroupFromImListSoapOut">
+ <wsdl:part name="RemoveDistributionGroupFromImListResult" element="tns:RemoveDistributionGroupFromImListResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="RemoveImGroupSoapIn">
+ <wsdl:part name="request" element="tns:RemoveImGroup"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="RemoveImGroupSoapOut">
+ <wsdl:part name="RemoveImGroupResult" element="tns:RemoveImGroupResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="SetImGroupSoapIn">
+ <wsdl:part name="request" element="tns:SetImGroup"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SetImGroupSoapOut">
+ <wsdl:part name="SetImGroupResult" element="tns:SetImGroupResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="SetImListMigrationCompletedSoapIn">
+ <wsdl:part name="request" element="tns:SetImListMigrationCompleted"/>
+ <wsdl:part name="Impersonation" element="t:ExchangeImpersonation"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SetImListMigrationCompletedSoapOut">
+ <wsdl:part name="SetImListMigrationCompletedResult" element="tns:SetImListMigrationCompletedResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- MRM Messages -->
+ <wsdl:message name="GetUserRetentionPolicyTagsSoapIn">
+ <wsdl:part name="request" element="tns:GetUserRetentionPolicyTags"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetUserRetentionPolicyTagsSoapOut">
+ <wsdl:part name="GetUserRetentionPolicyTagsResult" element="tns:GetUserRetentionPolicyTagsResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Photos -->
+ <wsdl:message name="GetUserPhotoSoapIn">
+ <wsdl:part name="request" element="tns:GetUserPhoto"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetUserPhotoSoapOut">
+ <wsdl:part name="GetUserPhotoResult" element="tns:GetUserPhotoResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="SetUserPhotoSoapIn">
+ <wsdl:part name="request" element="tns:SetUserPhoto"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="SetUserPhotoSoapOut">
+ <wsdl:part name="SetUserPhotoResult" element="tns:SetUserPhotoResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetMeetingSpaceSoapIn">
+ <wsdl:part name="request" element="tns:GetMeetingSpace"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetMeetingSpaceSoapOut">
+ <wsdl:part name="GetMeetingSpaceResult" element="tns:GetMeetingSpaceResponseMessage"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="DeleteMeetingSpaceSoapIn">
+ <wsdl:part name="request" element="tns:DeleteMeetingSpace"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteMeetingSpaceSoapOut">
+ <wsdl:part name="DeleteMeetingSpaceResult" element="tns:DeleteMeetingSpaceResponseMessage"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="UpdateMeetingSpaceSoapIn">
+ <wsdl:part name="request" element="tns:UpdateMeetingSpace"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateMeetingSpaceSoapOut">
+ <wsdl:part name="UpdateMeetingSpaceResult" element="tns:UpdateMeetingSpaceResponseMessage"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="CreateMeetingSpaceSoapIn">
+ <wsdl:part name="request" element="tns:CreateMeetingSpace"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="CreateMeetingSpaceSoapOut">
+ <wsdl:part name="CreateMeetingSpaceResult" element="tns:CreateMeetingSpaceResponseMessage"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="FindMeetingSpaceByJoinUrlSoapIn">
+ <wsdl:part name="request" element="tns:FindMeetingSpaceByJoinUrl"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="FindMeetingSpaceByJoinUrlSoapOut">
+ <wsdl:part name="FindMeetingSpaceByJoinUrlResult" element="tns:FindMeetingSpaceByJoinUrlResponseMessage"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="GetMeetingInstanceSoapIn">
+ <wsdl:part name="request" element="tns:GetMeetingInstanceRequest"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="GetMeetingInstanceSoapOut">
+ <wsdl:part name="GetMeetingInstanceResult" element="tns:GetMeetingInstanceResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="DeleteMeetingInstanceSoapIn">
+ <wsdl:part name="request" element="tns:DeleteMeetingInstanceRequest"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteMeetingInstanceSoapOut">
+ <wsdl:part name="DeleteMeetingInstanceResult" element="tns:DeleteMeetingInstanceResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="UpdateMeetingInstanceSoapIn">
+ <wsdl:part name="request" element="tns:UpdateMeetingInstanceRequest"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="UpdateMeetingInstanceSoapOut">
+ <wsdl:part name="UpdateMeetingInstanceResult" element="tns:UpdateMeetingInstanceResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:message name="CreateMeetingInstanceSoapIn">
+ <wsdl:part name="request" element="tns:CreateMeetingInstanceRequest"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ <wsdl:part name="ManagementRole" element="t:ManagementRole"/>
+ </wsdl:message>
+ <wsdl:message name="CreateMeetingInstanceSoapOut">
+ <wsdl:part name="CreateMeetingInstanceResult" element="tns:CreateMeetingInstanceResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Start Search Session Messages -->
+ <wsdl:message name="StartSearchSessionSoapIn">
+ <wsdl:part name="request" element="tns:StartSearchSession"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="StartSearchSessionSoapOut">
+ <wsdl:part name="StartSearchSessionResult" element="tns:StartSearchSessionResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Get Search Suggestions Messages -->
+ <wsdl:message name="GetSearchSuggestionsSoapIn">
+ <wsdl:part name="request" element="tns:GetSearchSuggestions"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetSearchSuggestionsSoapOut">
+ <wsdl:part name="GetSearchSuggestionsResult" element="tns:GetSearchSuggestionsResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Delete Search Suggestion Messages -->
+ <wsdl:message name="DeleteSearchSuggestionSoapIn">
+ <wsdl:part name="request" element="tns:DeleteSearchSuggestion"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="DeleteSearchSuggestionSoapOut">
+ <wsdl:part name="DeleteSearchSuggestionResult" element="tns:DeleteSearchSuggestionResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- Execute Search Messages> -->
+ <wsdl:message name="ExecuteSearchSoapIn">
+ <wsdl:part name="request" element="tns:ExecuteSearch"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="ExecuteSearchSoapOut">
+ <wsdl:part name="ExecuteSearchResult" element="tns:ExecuteSearchResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- End search Session Messages -->
+ <wsdl:message name="EndSearchSessionSoapIn">
+ <wsdl:part name="request" element="tns:EndSearchSession"/>
+ <wsdl:part name="MailboxCulture" element="t:MailboxCulture"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="EndSearchSessionSoapOut">
+ <wsdl:part name="EndSearchSessionResult" element="tns:EndSearchSessionResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- GetLastPrivateCatalogUpdate Messages -->
+ <wsdl:message name="GetLastPrivateCatalogUpdateSoapIn">
+ <wsdl:part name="request" element="tns:GetLastPrivateCatalogUpdate"/>
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetLastPrivateCatalogUpdateSoapOut">
+ <wsdl:part name="GetLastPrivateCatalogUpdateResult" element="tns:GetLastPrivateCatalogUpdateResponse"/>
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <!-- GetPrivateCatalogAddIns Messages -->
+ <wsdl:message name="GetPrivateCatalogAddInsSoapIn">
+ <wsdl:part name="request" element="tns:GetPrivateCatalogAddIns" />
+ <wsdl:part name="RequestVersion" element="t:RequestServerVersion"/>
+ </wsdl:message>
+ <wsdl:message name="GetPrivateCatalogAddInsSoapOut">
+ <wsdl:part name="GetPrivateCatalogAddInsResult" element="tns:GetPrivateCatalogAddInsResponse" />
+ <wsdl:part name="ServerVersion" element="t:ServerVersionInfo"/>
+ </wsdl:message>
+
+ <wsdl:portType name="ExchangeServicePortType">
+ <wsdl:operation name="ResolveNames">
+ <wsdl:input message="tns:ResolveNamesSoapIn" />
+ <wsdl:output message="tns:ResolveNamesSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="ExpandDL">
+ <wsdl:input message="tns:ExpandDLSoapIn" />
+ <wsdl:output message="tns:ExpandDLSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetServerTimeZones">
+ <wsdl:input message="tns:GetServerTimeZonesSoapIn" />
+ <wsdl:output message="tns:GetServerTimeZonesSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="FindFolder">
+ <wsdl:input message="tns:FindFolderSoapIn"/>
+ <wsdl:output message="tns:FindFolderSoapOut"/>
+ </wsdl:operation>
+ <wsdl:operation name="FindItem">
+ <wsdl:input message="tns:FindItemSoapIn"/>
+ <wsdl:output message="tns:FindItemSoapOut"/>
+ </wsdl:operation>
+ <wsdl:operation name="GetFolder">
+ <wsdl:input message="tns:GetFolderSoapIn" />
+ <wsdl:output message="tns:GetFolderSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="UploadItems">
+ <wsdl:input message="tns:UploadItemsSoapIn" />
+ <wsdl:output message="tns:UploadItemsSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="ExportItems">
+ <wsdl:input message="tns:ExportItemsSoapIn" />
+ <wsdl:output message="tns:ExportItemsSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="ConvertId">
+ <wsdl:input message="tns:ConvertIdSoapIn"/>
+ <wsdl:output message="tns:ConvertIdSoapOut"/>
+ </wsdl:operation>
+ <wsdl:operation name="CreateFolder">
+ <wsdl:input message="tns:CreateFolderSoapIn" />
+ <wsdl:output message="tns:CreateFolderSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="CreateFolderPath">
+ <wsdl:input message="tns:CreateFolderPathSoapIn" />
+ <wsdl:output message="tns:CreateFolderPathSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="DeleteFolder">
+ <wsdl:input message="tns:DeleteFolderSoapIn" />
+ <wsdl:output message="tns:DeleteFolderSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="EmptyFolder">
+ <wsdl:input message="tns:EmptyFolderSoapIn" />
+ <wsdl:output message="tns:EmptyFolderSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="UpdateFolder">
+ <wsdl:input message="tns:UpdateFolderSoapIn" />
+ <wsdl:output message="tns:UpdateFolderSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="MoveFolder">
+ <wsdl:input message="tns:MoveFolderSoapIn" />
+ <wsdl:output message="tns:MoveFolderSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="CopyFolder">
+ <wsdl:input message="tns:CopyFolderSoapIn" />
+ <wsdl:output message="tns:CopyFolderSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="Subscribe">
+ <wsdl:input message="tns:SubscribeSoapIn" />
+ <wsdl:output message="tns:SubscribeSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="Unsubscribe">
+ <wsdl:input message="tns:UnsubscribeSoapIn" />
+ <wsdl:output message="tns:UnsubscribeSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetEvents">
+ <wsdl:input message="tns:GetEventsSoapIn" />
+ <wsdl:output message="tns:GetEventsSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetStreamingEvents">
+ <wsdl:input message="tns:GetStreamingEventsSoapIn" />
+ <wsdl:output message="tns:GetStreamingEventsSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="SyncFolderHierarchy">
+ <wsdl:input message="tns:SyncFolderHierarchySoapIn" />
+ <wsdl:output message="tns:SyncFolderHierarchySoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="SyncFolderItems">
+ <wsdl:input message="tns:SyncFolderItemsSoapIn" />
+ <wsdl:output message="tns:SyncFolderItemsSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateManagedFolder">
+ <wsdl:input message="tns:CreateManagedFolderSoapIn" />
+ <wsdl:output message="tns:CreateManagedFolderSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="GetItem">
+ <wsdl:input message="tns:GetItemSoapIn" />
+ <wsdl:output message="tns:GetItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="CreateItem">
+ <wsdl:input message="tns:CreateItemSoapIn" />
+ <wsdl:output message="tns:CreateItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="DeleteItem">
+ <wsdl:input message="tns:DeleteItemSoapIn" />
+ <wsdl:output message="tns:DeleteItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="UpdateItem">
+ <wsdl:input message="tns:UpdateItemSoapIn" />
+ <wsdl:output message="tns:UpdateItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="UpdateItemInRecoverableItems">
+ <wsdl:input message="tns:UpdateItemInRecoverableItemsSoapIn" />
+ <wsdl:output message="tns:UpdateItemInRecoverableItemsSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="SendItem">
+ <wsdl:input message="tns:SendItemSoapIn" />
+ <wsdl:output message="tns:SendItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="MoveItem">
+ <wsdl:input message="tns:MoveItemSoapIn" />
+ <wsdl:output message="tns:MoveItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="CopyItem">
+ <wsdl:input message="tns:CopyItemSoapIn" />
+ <wsdl:output message="tns:CopyItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="ArchiveItem">
+ <wsdl:input message="tns:ArchiveItemSoapIn" />
+ <wsdl:output message="tns:ArchiveItemSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="CreateAttachment">
+ <wsdl:input message="tns:CreateAttachmentSoapIn" />
+ <wsdl:output message="tns:CreateAttachmentSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="DeleteAttachment">
+ <wsdl:input message="tns:DeleteAttachmentSoapIn" />
+ <wsdl:output message="tns:DeleteAttachmentSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetAttachment">
+ <wsdl:input message="tns:GetAttachmentSoapIn" />
+ <wsdl:output message="tns:GetAttachmentSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetClientAccessToken">
+ <wsdl:input message="tns:GetClientAccessTokenSoapIn" />
+ <wsdl:output message="tns:GetClientAccessTokenSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetDelegate">
+ <wsdl:input message="tns:GetDelegateSoapIn" />
+ <wsdl:output message="tns:GetDelegateSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="AddDelegate">
+ <wsdl:input message="tns:AddDelegateSoapIn" />
+ <wsdl:output message="tns:AddDelegateSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="RemoveDelegate">
+ <wsdl:input message="tns:RemoveDelegateSoapIn" />
+ <wsdl:output message="tns:RemoveDelegateSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="UpdateDelegate">
+ <wsdl:input message="tns:UpdateDelegateSoapIn" />
+ <wsdl:output message="tns:UpdateDelegateSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="CreateUserConfiguration">
+ <wsdl:input message="tns:CreateUserConfigurationSoapIn" />
+ <wsdl:output message="tns:CreateUserConfigurationSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="DeleteUserConfiguration">
+ <wsdl:input message="tns:DeleteUserConfigurationSoapIn" />
+ <wsdl:output message="tns:DeleteUserConfigurationSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetUserConfiguration">
+ <wsdl:input message="tns:GetUserConfigurationSoapIn" />
+ <wsdl:output message="tns:GetUserConfigurationSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="GetSpecificUserConfiguration">
+ <wsdl:input message="tns:GetSpecificUserConfigurationSoapIn" />
+ <wsdl:output message="tns:GetSpecificUserConfigurationSoapOut" />
+ </wsdl:operation>
+ <wsdl:operation name="UpdateUserConfiguration">
+ <wsdl:input message="tns:UpdateUserConfigurationSoapIn" />
+ <wsdl:output message="tns:UpdateUserConfigurationSoapOut" />
+ </wsdl:operation>
+
+ <!-- Availability Service Operations -->
+
+ <!-- GetUserAvailability -->
+ <wsdl:operation name="GetUserAvailability">
+ <wsdl:input message="tns:GetUserAvailabilitySoapIn" />
+ <wsdl:output message="tns:GetUserAvailabilitySoapOut" />
+ </wsdl:operation>
+
+ <!-- GetUserOofSettings -->
+ <wsdl:operation name="GetUserOofSettings">
+ <wsdl:input message="tns:GetUserOofSettingsSoapIn" />
+ <wsdl:output message="tns:GetUserOofSettingsSoapOut" />
+ </wsdl:operation>
+
+ <!-- SetUserOofSettings -->
+ <wsdl:operation name="SetUserOofSettings">
+ <wsdl:input message="tns:SetUserOofSettingsSoapIn" />
+ <wsdl:output message="tns:SetUserOofSettingsSoapOut" />
+ </wsdl:operation>
+
+ <!-- GetServiceConfiguration Operations -->
+ <wsdl:operation name="GetServiceConfiguration">
+ <wsdl:input message="tns:GetServiceConfigurationSoapIn" />
+ <wsdl:output message="tns:GetServiceConfigurationSoapOut" />
+ </wsdl:operation>
+
+ <!-- MailTips Operations -->
+ <wsdl:operation name="GetMailTips">
+ <wsdl:input message="tns:GetMailTipsSoapIn" />
+ <wsdl:output message="tns:GetMailTipsSoapOut" />
+ </wsdl:operation>
+
+ <!-- UM Operations -->
+ <wsdl:operation name="PlayOnPhone">
+ <wsdl:input message="tns:PlayOnPhoneSoapIn" />
+ <wsdl:output message="tns:PlayOnPhoneSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="GetPhoneCallInformation">
+ <wsdl:input message="tns:GetPhoneCallInformationSoapIn" />
+ <wsdl:output message="tns:GetPhoneCallInformationSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="DisconnectPhoneCall">
+ <wsdl:input message="tns:DisconnectPhoneCallSoapIn" />
+ <wsdl:output message="tns:DisconnectPhoneCallSoapOut" />
+ </wsdl:operation>
+
+ <!-- Sharing Operations -->
+ <wsdl:operation name="GetSharingMetadata">
+ <wsdl:input message="tns:GetSharingMetadataSoapIn" />
+ <wsdl:output message="tns:GetSharingMetadataSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="RefreshSharingFolder">
+ <wsdl:input message="tns:RefreshSharingFolderSoapIn" />
+ <wsdl:output message="tns:RefreshSharingFolderSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="GetSharingFolder">
+ <wsdl:input message="tns:GetSharingFolderSoapIn" />
+ <wsdl:output message="tns:GetSharingFolderSoapOut" />
+ </wsdl:operation>
+
+ <!-- SetTeamMailbox -->
+ <wsdl:operation name="SetTeamMailbox">
+ <wsdl:input message="tns:SetTeamMailboxSoapIn" />
+ <wsdl:output message="tns:SetTeamMailboxSoapOut" />
+ </wsdl:operation>
+
+ <!-- UnpinTeamMailbox -->
+ <wsdl:operation name="UnpinTeamMailbox">
+ <wsdl:input message="tns:UnpinTeamMailboxSoapIn" />
+ <wsdl:output message="tns:UnpinTeamMailboxSoapOut" />
+ </wsdl:operation>
+
+ <!-- Find A Room Service Operations -->
+
+ <!-- GetRoomLists -->
+ <wsdl:operation name="GetRoomLists">
+ <wsdl:input message="tns:GetRoomListsSoapIn" />
+ <wsdl:output message="tns:GetRoomListsSoapOut" />
+ </wsdl:operation>
+
+ <!-- GetRooms -->
+ <wsdl:operation name="GetRooms">
+ <wsdl:input message="tns:GetRoomsSoapIn" />
+ <wsdl:output message="tns:GetRoomsSoapOut" />
+ </wsdl:operation>
+
+ <!-- MessageTracking -->
+ <wsdl:operation name="FindMessageTrackingReport">
+ <wsdl:input message="tns:FindMessageTrackingReportSoapIn"/>
+ <wsdl:output message="tns:FindMessageTrackingReportSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetMessageTrackingReport">
+ <wsdl:input message="tns:GetMessageTrackingReportSoapIn"/>
+ <wsdl:output message="tns:GetMessageTrackingReportSoapOut"/>
+ </wsdl:operation>
+
+ <!--Conversations-->
+ <wsdl:operation name ="FindConversation">
+ <wsdl:input message="tns:FindConversationSoapIn" />
+ <wsdl:output message="tns:FindConversationSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name ="ApplyConversationAction">
+ <wsdl:input message="tns:ApplyConversationActionSoapIn" />
+ <wsdl:output message="tns:ApplyConversationActionSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name ="GetConversationItems">
+ <wsdl:input message="tns:GetConversationItemsSoapIn" />
+ <wsdl:output message="tns:GetConversationItemsSoapOut" />
+ </wsdl:operation>
+
+ <!--FindPeople-->
+ <wsdl:operation name="FindPeople">
+ <wsdl:input message="tns:FindPeopleSoapIn" />
+ <wsdl:output message="tns:FindPeopleSoapOut" />
+ </wsdl:operation>
+
+ <!--FindTags-->
+ <wsdl:operation name="FindTags">
+ <wsdl:input message="tns:FindTagsSoapIn" />
+ <wsdl:output message="tns:FindTagsSoapOut" />
+ </wsdl:operation>
+
+ <!--AddTag-->
+ <wsdl:operation name="AddTag">
+ <wsdl:input message="tns:AddTagSoapIn" />
+ <wsdl:output message="tns:AddTagSoapOut" />
+ </wsdl:operation>
+
+ <!--HideTag-->
+ <wsdl:operation name="HideTag">
+ <wsdl:input message="tns:HideTagSoapIn" />
+ <wsdl:output message="tns:HideTagSoapOut" />
+ </wsdl:operation>
+
+ <!--GetPersona-->
+ <wsdl:operation name="GetPersona">
+ <wsdl:input message="tns:GetPersonaSoapIn" />
+ <wsdl:output message="tns:GetPersonaSoapOut" />
+ </wsdl:operation>
+
+ <!-- Inbox Rules -->
+ <wsdl:operation name="GetInboxRules">
+ <wsdl:input message="tns:GetInboxRulesSoapIn" />
+ <wsdl:output message="tns:GetInboxRulesSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="UpdateInboxRules">
+ <wsdl:input message="tns:UpdateInboxRulesSoapIn" />
+ <wsdl:output message="tns:UpdateInboxRulesSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="GetPasswordExpirationDate">
+ <wsdl:input message="tns:GetPasswordExpirationDateSoapIn" />
+ <wsdl:output message="tns:GetPasswordExpirationDateSoapOut" />
+ </wsdl:operation>
+
+ <!-- Mailbox Search Operations -->
+ <wsdl:operation name="GetSearchableMailboxes">
+ <wsdl:input message="tns:GetSearchableMailboxesSoapIn"/>
+ <wsdl:output message="tns:GetSearchableMailboxesSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="SearchMailboxes">
+ <wsdl:input message="tns:SearchMailboxesSoapIn"/>
+ <wsdl:output message="tns:SearchMailboxesSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetDiscoverySearchConfiguration">
+ <wsdl:input message="tns:GetDiscoverySearchConfigurationSoapIn"/>
+ <wsdl:output message="tns:GetDiscoverySearchConfigurationSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetHoldOnMailboxes">
+ <wsdl:input message="tns:GetHoldOnMailboxesSoapIn"/>
+ <wsdl:output message="tns:GetHoldOnMailboxesSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="SetHoldOnMailboxes">
+ <wsdl:input message="tns:SetHoldOnMailboxesSoapIn"/>
+ <wsdl:output message="tns:SetHoldOnMailboxesSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetNonIndexableItemStatistics">
+ <wsdl:input message="tns:GetNonIndexableItemStatisticsSoapIn"/>
+ <wsdl:output message="tns:GetNonIndexableItemStatisticsSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetNonIndexableItemDetails">
+ <wsdl:input message="tns:GetNonIndexableItemDetailsSoapIn"/>
+ <wsdl:output message="tns:GetNonIndexableItemDetailsSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="MarkAllItemsAsRead">
+ <wsdl:input message="tns:MarkAllItemsAsReadSoapIn" />
+ <wsdl:output message="tns:MarkAllItemsAsReadSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="MarkAsJunk">
+ <wsdl:input message="tns:MarkAsJunkSoapIn" />
+ <wsdl:output message="tns:MarkAsJunkSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="ReportMessage">
+ <wsdl:input message="tns:ReportMessageSoapIn" />
+ <wsdl:output message="tns:ReportMessageSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="GetAppManifests">
+ <wsdl:input message="tns:GetAppManifestsSoapIn" />
+ <wsdl:output message="tns:GetAppManifestsSoapOut" />
+ </wsdl:operation>
+
+ <!-- Unified Contact Store Operations -->
+ <wsdl:operation name="AddNewImContactToGroup">
+ <wsdl:input message="tns:AddNewImContactToGroupSoapIn"/>
+ <wsdl:output message="tns:AddNewImContactToGroupSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddNewTelUriContactToGroup">
+ <wsdl:input message="tns:AddNewTelUriContactToGroupSoapIn"/>
+ <wsdl:output message="tns:AddNewTelUriContactToGroupSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddImContactToGroup">
+ <wsdl:input message="tns:AddImContactToGroupSoapIn"/>
+ <wsdl:output message="tns:AddImContactToGroupSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveImContactFromGroup">
+ <wsdl:input message="tns:RemoveImContactFromGroupSoapIn"/>
+ <wsdl:output message="tns:RemoveImContactFromGroupSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddImGroup">
+ <wsdl:input message="tns:AddImGroupSoapIn"/>
+ <wsdl:output message="tns:AddImGroupSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddDistributionGroupToImList">
+ <wsdl:input message="tns:AddDistributionGroupToImListSoapIn"/>
+ <wsdl:output message="tns:AddDistributionGroupToImListSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetImItemList">
+ <wsdl:input message="tns:GetImItemListSoapIn"/>
+ <wsdl:output message="tns:GetImItemListSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetImItems">
+ <wsdl:input message="tns:GetImItemsSoapIn"/>
+ <wsdl:output message="tns:GetImItemsSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveContactFromImList">
+ <wsdl:input message="tns:RemoveContactFromImListSoapIn"/>
+ <wsdl:output message="tns:RemoveContactFromImListSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveDistributionGroupFromImList">
+ <wsdl:input message="tns:RemoveDistributionGroupFromImListSoapIn"/>
+ <wsdl:output message="tns:RemoveDistributionGroupFromImListSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveImGroup">
+ <wsdl:input message="tns:RemoveImGroupSoapIn"/>
+ <wsdl:output message="tns:RemoveImGroupSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="SetImGroup">
+ <wsdl:input message="tns:SetImGroupSoapIn"/>
+ <wsdl:output message="tns:SetImGroupSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="SetImListMigrationCompleted">
+ <wsdl:input message="tns:SetImListMigrationCompletedSoapIn"/>
+ <wsdl:output message="tns:SetImListMigrationCompletedSoapOut"/>
+ </wsdl:operation>
+
+ <!-- MRM Operations -->
+ <wsdl:operation name="GetUserRetentionPolicyTags">
+ <wsdl:input message="tns:GetUserRetentionPolicyTagsSoapIn"/>
+ <wsdl:output message="tns:GetUserRetentionPolicyTagsSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="InstallApp">
+ <wsdl:input message="tns:InstallAppSoapIn"/>
+ <wsdl:output message="tns:InstallAppSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="UninstallApp">
+ <wsdl:input message="tns:UninstallAppSoapIn"/>
+ <wsdl:output message="tns:UninstallAppSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="DisableApp">
+ <wsdl:input message="tns:DisableAppSoapIn"/>
+ <wsdl:output message="tns:DisableAppSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetAppMarketplaceUrl">
+ <wsdl:input message="tns:GetAppMarketplaceUrlSoapIn"/>
+ <wsdl:output message="tns:GetAppMarketplaceUrlSoapOut"/>
+ </wsdl:operation>
+
+ <!-- FindAvailableMeetingTimes (PortType) Operation -->
+ <wsdl:operation name="FindAvailableMeetingTimes">
+ <wsdl:input message="tns:FindAvailableMeetingTimesSoapIn" />
+ <wsdl:output message="tns:FindAvailableMeetingTimesSoapOut" />
+ </wsdl:operation>
+
+ <!-- FindMeetingTimeCandidates (PortType) Operation -->
+ <wsdl:operation name="FindMeetingTimeCandidates">
+ <wsdl:input message="tns:FindMeetingTimeCandidatesSoapIn" />
+ <wsdl:output message="tns:FindMeetingTimeCandidatesSoapOut" />
+ </wsdl:operation>
+
+ <!-- Photos -->
+ <wsdl:operation name="GetUserPhoto">
+ <wsdl:input message="tns:GetUserPhotoSoapIn"/>
+ <wsdl:output message="tns:GetUserPhotoSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="SetUserPhoto">
+ <wsdl:input message="tns:SetUserPhotoSoapIn"/>
+ <wsdl:output message="tns:SetUserPhotoSoapOut"/>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetMeetingSpace">
+ <wsdl:input message="tns:GetMeetingSpaceSoapIn" />
+ <wsdl:output message="tns:GetMeetingSpaceSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="DeleteMeetingSpace">
+ <wsdl:input message="tns:DeleteMeetingSpaceSoapIn" />
+ <wsdl:output message="tns:DeleteMeetingSpaceSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="UpdateMeetingSpace">
+ <wsdl:input message="tns:UpdateMeetingSpaceSoapIn" />
+ <wsdl:output message="tns:UpdateMeetingSpaceSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateMeetingSpace">
+ <wsdl:input message="tns:CreateMeetingSpaceSoapIn" />
+ <wsdl:output message="tns:CreateMeetingSpaceSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="FindMeetingSpaceByJoinUrl">
+ <wsdl:input message="tns:FindMeetingSpaceByJoinUrlSoapIn" />
+ <wsdl:output message="tns:FindMeetingSpaceByJoinUrlSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="GetMeetingInstance">
+ <wsdl:input message="tns:GetMeetingInstanceSoapIn" />
+ <wsdl:output message="tns:GetMeetingInstanceSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="DeleteMeetingInstance">
+ <wsdl:input message="tns:DeleteMeetingInstanceSoapIn" />
+ <wsdl:output message="tns:DeleteMeetingInstanceSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="UpdateMeetingInstance">
+ <wsdl:input message="tns:UpdateMeetingInstanceSoapIn" />
+ <wsdl:output message="tns:UpdateMeetingInstanceSoapOut" />
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateMeetingInstance">
+ <wsdl:input message="tns:CreateMeetingInstanceSoapIn" />
+ <wsdl:output message="tns:CreateMeetingInstanceSoapOut" />
+ </wsdl:operation>
+
+ <!-- StartSearchSession (PortType) operation -->
+ <wsdl:operation name="StartSearchSession">
+ <wsdl:input message="tns:StartSearchSessionSoapIn" />
+ <wsdl:output message="tns:StartSearchSessionSoapOut" />
+ </wsdl:operation>
+
+ <!-- GetSearchSuggestions (PortType) operation -->
+ <wsdl:operation name="GetSearchSuggestions">
+ <wsdl:input message="tns:GetSearchSuggestionsSoapIn" />
+ <wsdl:output message="tns:GetSearchSuggestionsSoapOut" />
+ </wsdl:operation>
+
+ <!-- DeleteSearchSuggestion (PortType) operation -->
+ <wsdl:operation name="DeleteSearchSuggestion">
+ <wsdl:input message="tns:DeleteSearchSuggestionSoapIn" />
+ <wsdl:output message="tns:DeleteSearchSuggestionSoapOut" />
+ </wsdl:operation>
+
+ <!-- ExecuteSearch (PortType) operation -->
+ <wsdl:operation name="ExecuteSearch">
+ <wsdl:input message="tns:ExecuteSearchSoapIn" />
+ <wsdl:output message="tns:ExecuteSearchSoapOut" />
+ </wsdl:operation>
+
+ <!-- EndSearchSession (PortType) operation -->
+ <wsdl:operation name="EndSearchSession">
+ <wsdl:input message="tns:EndSearchSessionSoapIn" />
+ <wsdl:output message="tns:EndSearchSessionSoapOut" />
+ </wsdl:operation>
+
+ <!-- GetLastPrivateCatalogUpdate (PortType) operation -->
+ <wsdl:operation name="GetLastPrivateCatalogUpdate">
+ <wsdl:input message="tns:GetLastPrivateCatalogUpdateSoapIn" />
+ <wsdl:output message="tns:GetLastPrivateCatalogUpdateSoapOut" />
+ </wsdl:operation>
+
+ <!-- GetPrivateCatalogAddIns (PortType) operation -->
+ <wsdl:operation name="GetPrivateCatalogAddIns">
+ <wsdl:input message="tns:GetPrivateCatalogAddInsSoapIn" />
+ <wsdl:output message="tns:GetPrivateCatalogAddInsSoapOut" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+ <wsdl:binding name="ExchangeServiceBinding" type="tns:ExchangeServicePortType">
+ <wsdl:documentation>
+ <wsi:Claim conformsTo="http://ws-i.org/profiles/basic/1.0" xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/" />
+ </wsdl:documentation>
+ <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
+ <wsdl:operation name="ResolveNames">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:ResolveNamesSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:ResolveNamesSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:ResolveNamesSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ResolveNamesResult" use="literal" />
+ <soap:header message="tns:ResolveNamesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="ExpandDL">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ExpandDL" />
+ <wsdl:input>
+ <soap:header message="tns:ExpandDLSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:ExpandDLSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:ExpandDLSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ExpandDLResult" use="literal" />
+ <soap:header message="tns:ExpandDLSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetServerTimeZones">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetServerTimeZones" />
+ <wsdl:input>
+ <soap:header message="tns:GetServerTimeZonesSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetServerTimeZonesSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetServerTimeZonesResult" use="literal" />
+ <soap:header message="tns:GetServerTimeZonesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="FindFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindFolder"/>
+ <wsdl:input>
+ <soap:header message="tns:FindFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:FindFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:FindFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:FindFolderSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:header message="tns:FindFolderSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindFolderResult" use="literal" />
+ <soap:header message="tns:FindFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="FindItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindItem"/>
+ <wsdl:input>
+ <soap:header message="tns:FindItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:FindItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:FindItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:FindItemSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:header message="tns:FindItemSoapIn" part="DateTimePrecision" use="literal" />
+ <soap:header message="tns:FindItemSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindItemResult" use="literal" />
+ <soap:header message="tns:FindItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetFolder" />
+ <wsdl:input>
+ <soap:header message="tns:GetFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetFolderSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:header message="tns:GetFolderSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetFolderResult" use="literal" />
+ <soap:header message="tns:GetFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="ConvertId">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ConvertId" />
+ <wsdl:input>
+ <soap:header message="tns:ConvertIdSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:ConvertIdSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ConvertIdResult" use="literal" />
+ <soap:header message="tns:ConvertIdSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="UploadItems">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UploadItems" />
+ <wsdl:input>
+ <soap:header message="tns:UploadItemsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:UploadItemsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:UploadItemsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UploadItemsResult" use="literal" />
+ <soap:header message="tns:UploadItemsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="ExportItems">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ExportItems" />
+ <wsdl:input>
+ <soap:header message="tns:ExportItemsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:ExportItemsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:ExportItemsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:ExportItemsSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ExportItemsResult" use="literal" />
+ <soap:header message="tns:ExportItemsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateFolderPath">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateFolderPath" />
+ <wsdl:input>
+ <soap:header message="tns:CreateFolderPathSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CreateFolderPathSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CreateFolderPathSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:CreateFolderPathSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateFolderPathResult" use="literal" />
+ <soap:header message="tns:CreateFolderPathSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="CreateFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateFolder" />
+ <wsdl:input>
+ <soap:header message="tns:CreateFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CreateFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CreateFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:CreateFolderSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateFolderResult" use="literal" />
+ <soap:header message="tns:CreateFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="DeleteFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DeleteFolder" />
+ <wsdl:input>
+ <soap:header message="tns:DeleteFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:DeleteFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:DeleteFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DeleteFolderResult" use="literal" />
+ <soap:header message="tns:DeleteFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="EmptyFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/EmptyFolder" />
+ <wsdl:input>
+ <soap:header message="tns:EmptyFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:EmptyFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:EmptyFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="EmptyFolderResult" use="literal" />
+ <soap:header message="tns:EmptyFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="UpdateFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateFolder" />
+ <wsdl:input>
+ <soap:header message="tns:UpdateFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:UpdateFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:UpdateFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:UpdateFolderSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateFolderResult" use="literal" />
+ <soap:header message="tns:UpdateFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="MoveFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/MoveFolder" />
+ <wsdl:input>
+ <soap:header message="tns:MoveFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:MoveFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:MoveFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="MoveFolderResult" use="literal" />
+ <soap:header message="tns:MoveFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="CopyFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CopyFolder" />
+ <wsdl:input>
+ <soap:header message="tns:CopyFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CopyFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CopyFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CopyFolderResult" use="literal" />
+ <soap:header message="tns:CopyFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="Subscribe">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/Subscribe" />
+ <wsdl:input>
+ <soap:header message="tns:SubscribeSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:SubscribeSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:SubscribeSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SubscribeResult" use="literal" />
+ <soap:header message="tns:SubscribeSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="Unsubscribe">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/Unsubscribe" />
+ <wsdl:input>
+ <soap:header message="tns:UnsubscribeSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:UnsubscribeSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:UnsubscribeSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UnsubscribeResult" use="literal" />
+ <soap:header message="tns:UnsubscribeSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetEvents">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetEvents" />
+ <wsdl:input>
+ <soap:header message="tns:GetEventsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetEventsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetEventsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetEventsResult" use="literal" />
+ <soap:header message="tns:GetEventsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetStreamingEvents">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetEvents" />
+ <wsdl:input>
+ <soap:header message="tns:GetStreamingEventsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetStreamingEventsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetStreamingEventsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetStreamingEventsResult" use="literal" />
+ <soap:header message="tns:GetStreamingEventsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="SyncFolderHierarchy">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SyncFolderHierarchy" />
+ <wsdl:input>
+ <soap:header message="tns:SyncFolderHierarchySoapIn" part="Impersonation" use="literal"></soap:header>
+ <soap:header message="tns:SyncFolderHierarchySoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:SyncFolderHierarchySoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SyncFolderHierarchyResult" use="literal" />
+ <soap:header message="tns:SyncFolderHierarchySoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="SyncFolderItems">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SyncFolderItems" />
+ <wsdl:input>
+ <soap:header message="tns:SyncFolderItemsSoapIn" part="Impersonation" use="literal"></soap:header>
+ <soap:header message="tns:SyncFolderItemsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:SyncFolderItemsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SyncFolderItemsResult" use="literal" />
+ <soap:header message="tns:SyncFolderItemsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetItem" />
+ <wsdl:input>
+ <soap:header message="tns:GetItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetItemSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:header message="tns:GetItemSoapIn" part="DateTimePrecision" use="literal" />
+ <soap:header message="tns:GetItemSoapIn" part="ManagementRole" use="literal" />
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetItemResult" use="literal" />
+ <soap:header message="tns:GetItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="CreateItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateItem" />
+ <wsdl:input>
+ <soap:header message="tns:CreateItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CreateItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CreateItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:CreateItemSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateItemResult" use="literal" />
+ <soap:header message="tns:CreateItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="DeleteItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DeleteItem" />
+ <wsdl:input>
+ <soap:header message="tns:DeleteItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:DeleteItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:DeleteItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DeleteItemResult" use="literal" />
+ <soap:header message="tns:DeleteItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="UpdateItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateItem" />
+ <wsdl:input>
+ <soap:header message="tns:UpdateItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:UpdateItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:UpdateItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:UpdateItemSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateItemResult" use="literal" />
+ <soap:header message="tns:UpdateItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="UpdateItemInRecoverableItems">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateItemInRecoverableItems" />
+ <wsdl:input>
+ <soap:header message="tns:UpdateItemInRecoverableItemsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:UpdateItemInRecoverableItemsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:UpdateItemInRecoverableItemsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:UpdateItemInRecoverableItemsSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:header message="tns:UpdateItemInRecoverableItemsSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateItemInRecoverableItemsResult" use="literal" />
+ <soap:header message="tns:UpdateItemInRecoverableItemsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="SendItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SendItem" />
+ <wsdl:input>
+ <soap:header message="tns:SendItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:SendItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:SendItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SendItemResult" use="literal" />
+ <soap:header message="tns:SendItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="MoveItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/MoveItem" />
+ <wsdl:input>
+ <soap:header message="tns:MoveItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:MoveItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:MoveItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="MoveItemResult" use="literal" />
+ <soap:header message="tns:MoveItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="CopyItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CopyItem" />
+ <wsdl:input>
+ <soap:header message="tns:CopyItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CopyItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CopyItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CopyItemResult" use="literal" />
+ <soap:header message="tns:CopyItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="ArchiveItem">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ArchiveItem" />
+ <wsdl:input>
+ <soap:header message="tns:ArchiveItemSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:ArchiveItemSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:ArchiveItemSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ArchiveItemResult" use="literal" />
+ <soap:header message="tns:ArchiveItemSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="CreateAttachment">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateAttachment" />
+ <wsdl:input>
+ <soap:header message="tns:CreateAttachmentSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CreateAttachmentSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CreateAttachmentSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:CreateAttachmentSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateAttachmentResult" use="literal" />
+ <soap:header message="tns:CreateAttachmentSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="DeleteAttachment">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DeleteAttachment" />
+ <wsdl:input>
+ <soap:header message="tns:DeleteAttachmentSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:DeleteAttachmentSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:DeleteAttachmentSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DeleteAttachmentResult" use="literal" />
+ <soap:header message="tns:DeleteAttachmentSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetAttachment">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetAttachment" />
+ <wsdl:input>
+ <soap:header message="tns:GetAttachmentSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetAttachmentSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetAttachmentSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetAttachmentSoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetAttachmentResult" use="literal" />
+ <soap:header message="tns:GetAttachmentSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetClientAccessToken">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetClientAccessToken" />
+ <wsdl:input>
+ <soap:header message="tns:GetClientAccessTokenSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetClientAccessTokenResult" use="literal" />
+ <soap:header message="tns:GetClientAccessTokenSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateManagedFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateManagedFolder" />
+ <wsdl:input>
+ <soap:header message="tns:CreateManagedFolderSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CreateManagedFolderSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CreateManagedFolderSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateManagedFolderResult" use="literal" />
+ <soap:header message="tns:CreateManagedFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetDelegate">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetDelegate" />
+ <wsdl:input>
+ <soap:header message="tns:GetDelegateSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetDelegateSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetDelegateSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetDelegateResult" use="literal" />
+ <soap:header message="tns:GetDelegateSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddDelegate">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/AddDelegate" />
+ <wsdl:input>
+ <soap:header message="tns:AddDelegateSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:AddDelegateSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:AddDelegateSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="AddDelegateResult" use="literal" />
+ <soap:header message="tns:AddDelegateSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveDelegate">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/RemoveDelegate" />
+ <wsdl:input>
+ <soap:header message="tns:RemoveDelegateSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:RemoveDelegateSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:RemoveDelegateSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="RemoveDelegateResult" use="literal" />
+ <soap:header message="tns:RemoveDelegateSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="UpdateDelegate">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateDelegate" />
+ <wsdl:input>
+ <soap:header message="tns:UpdateDelegateSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:UpdateDelegateSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:UpdateDelegateSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateDelegateResult" use="literal" />
+ <soap:header message="tns:UpdateDelegateSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateUserConfiguration">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateUserConfiguration" />
+ <wsdl:input>
+ <soap:header message="tns:CreateUserConfigurationSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:CreateUserConfigurationSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:CreateUserConfigurationSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateUserConfigurationResult" use="literal" />
+ <soap:header message="tns:CreateUserConfigurationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="DeleteUserConfiguration">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DeleteUserConfiguration" />
+ <wsdl:input>
+ <soap:header message="tns:DeleteUserConfigurationSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:DeleteUserConfigurationSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:DeleteUserConfigurationSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DeleteUserConfigurationResult" use="literal" />
+ <soap:header message="tns:DeleteUserConfigurationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetUserConfiguration">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetUserConfiguration" />
+ <wsdl:input>
+ <soap:header message="tns:GetUserConfigurationSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetUserConfigurationSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetUserConfigurationSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetUserConfigurationResult" use="literal" />
+ <soap:header message="tns:GetUserConfigurationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetSpecificUserConfiguration">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetSpecificUserConfiguration" />
+ <wsdl:input>
+ <soap:header message="tns:GetSpecificUserConfigurationSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetSpecificUserConfigurationSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetSpecificUserConfigurationSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetSpecificUserConfigurationResult" use="literal" />
+ <soap:header message="tns:GetSpecificUserConfigurationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="UpdateUserConfiguration">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateUserConfiguration" />
+ <wsdl:input>
+ <soap:header message="tns:UpdateUserConfigurationSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:UpdateUserConfigurationSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:UpdateUserConfigurationSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateUserConfigurationResult" use="literal" />
+ <soap:header message="tns:UpdateUserConfigurationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Availability Service -->
+
+ <!-- GetUserAvailability -->
+ <wsdl:operation name="GetUserAvailability">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetUserAvailability" />
+ <wsdl:input>
+ <soap:header message="tns:GetUserAvailabilitySoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetUserAvailabilitySoapIn" part="TimeZoneContext" use="literal"/>
+ <soap:header message="tns:GetUserAvailabilitySoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="GetUserAvailabilityRequest" use="literal" />
+ <soap:header message="tns:GetUserAvailabilitySoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetUserAvailabilityResult" use="literal" />
+ <soap:header message="tns:GetUserAvailabilitySoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetUserOofSettings -->
+ <wsdl:operation name="GetUserOofSettings">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetUserOofSettings" />
+ <wsdl:input>
+ <soap:header message="tns:GetUserOofSettingsSoapIn" part="Impersonation" use="literal"/>
+ <soap:body parts="GetUserOofSettingsRequest" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetUserOofSettingsResult" use="literal" />
+ <soap:header message="tns:GetUserOofSettingsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- SetUserOofSettings -->
+ <wsdl:operation name="SetUserOofSettings">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SetUserOofSettings" />
+ <wsdl:input>
+ <soap:header message="tns:SetUserOofSettingsSoapIn" part="Impersonation" use="literal"/>
+ <soap:body parts="SetUserOofSettingsRequest" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SetUserOofSettingsResult" use="literal" />
+ <soap:header message="tns:SetUserOofSettingsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetServiceConfiguration Bindings -->
+
+ <!-- GetServiceConfiguration -->
+ <wsdl:operation name="GetServiceConfiguration">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetServiceConfiguration" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:GetServiceConfigurationSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetServiceConfigurationSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetServiceConfigurationSoapIn" part="MailboxCulture" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetServiceConfigurationResult" use="literal" />
+ <soap:header message="tns:GetServiceConfigurationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetMailTips -->
+ <wsdl:operation name="GetMailTips">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetMailTips" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:GetMailTipsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetMailTipsSoapIn" part="MailboxCulture" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetMailTipsResult" use="literal" />
+ <soap:header message="tns:GetMailTipsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- UMBindings -->
+ <wsdl:operation name="PlayOnPhone">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/PlayOnPhone" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:PlayOnPhoneSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:PlayOnPhoneSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:PlayOnPhoneSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="PlayOnPhoneResult" use="literal" />
+ <soap:header message="tns:PlayOnPhoneSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetPhoneCallInformation">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetPhoneCallInformation" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:GetPhoneCallInformationSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetPhoneCallInformationSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetPhoneCallInformationSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetPhoneCallInformationResult" use="literal" />
+ <soap:header message="tns:GetPhoneCallInformationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="DisconnectPhoneCall">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DisconnectPhoneCall" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:DisconnectPhoneCallSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:DisconnectPhoneCallSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:DisconnectPhoneCallSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DisconnectPhoneCallResult" use="literal" />
+ <soap:header message="tns:DisconnectPhoneCallSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Sharing -->
+
+ <!-- GetSharingMetadata -->
+ <wsdl:operation name="GetSharingMetadata">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetSharingMetadata" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:GetSharingMetadataSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetSharingMetadataResult" use="literal" />
+ <soap:header message="tns:GetSharingMetadataSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- RefreshSharingFolder -->
+ <wsdl:operation name="RefreshSharingFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/RefreshSharingFolder" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:RefreshSharingFolderSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="RefreshSharingFolderResult" use="literal" />
+ <soap:header message="tns:RefreshSharingFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetSharingFolder -->
+ <wsdl:operation name="GetSharingFolder">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetSharingFolder" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:GetSharingFolderSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetSharingFolderResult" use="literal" />
+ <soap:header message="tns:GetSharingFolderSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- SetTeamMailbox -->
+ <wsdl:operation name="SetTeamMailbox">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SetTeamMailbox" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:SetTeamMailboxSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:SetTeamMailboxSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SetTeamMailboxResult" use="literal" />
+ <soap:header message="tns:SetTeamMailboxSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- UnpinTeamMailbox -->
+ <wsdl:operation name="UnpinTeamMailbox">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UnpinTeamMailbox" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:UnpinTeamMailboxSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UnpinTeamMailboxResult" use="literal" />
+ <soap:header message="tns:UnpinTeamMailboxSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Find A Room Service -->
+
+ <!-- GetRoomLists -->
+ <wsdl:operation name="GetRoomLists">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetRoomLists" />
+ <wsdl:input>
+ <soap:body parts="GetRoomListsRequest" use="literal" />
+ <soap:header message="tns:GetRoomListsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetRoomListsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetRoomListsSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+
+ <wsdl:output>
+ <soap:body parts="GetRoomListsResult" use="literal" />
+ <soap:header message="tns:GetRoomListsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetRooms -->
+ <wsdl:operation name="GetRooms">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetRooms" />
+ <wsdl:input>
+ <soap:body parts="GetRoomsRequest" use="literal" />
+ <soap:header message="tns:GetRoomsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetRoomsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetRoomsSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+
+ <wsdl:output>
+ <soap:body parts="GetRoomsResult" use="literal" />
+ <soap:header message="tns:GetRoomsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- MessageTracking -->
+ <wsdl:operation name="FindMessageTrackingReport">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindMessageTrackingReport" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:FindMessageTrackingReportSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindMessageTrackingReportResult" use="literal" />
+ <soap:header message="tns:FindMessageTrackingReportSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetMessageTrackingReport">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetMessageTrackingReport" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal"/>
+ <soap:header message="tns:GetMessageTrackingReportSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetMessageTrackingReportResult" use="literal" />
+ <soap:header message="tns:GetMessageTrackingReportSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!--Conversations-->
+ <wsdl:operation name="FindConversation">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindConversation" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:FindConversationSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:FindConversationSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindConversationResult" use="literal" />
+ <soap:header message="tns:FindConversationSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="ApplyConversationAction">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ApplyConversationAction" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:ApplyConversationActionSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:ApplyConversationActionSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ApplyConversationActionResult" use="literal" />
+ <soap:header message="tns:ApplyConversationActionSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetConversationItems">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetConversationItems" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:GetConversationItemsSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:GetConversationItemsSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetConversationItemsResult" use="literal" />
+ <soap:header message="tns:GetConversationItemsSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!--FindPeople-->
+ <wsdl:operation name="FindPeople">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindPeople" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:FindPeopleSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:FindPeopleSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindPeopleResult" use="literal" />
+ <soap:header message="tns:FindPeopleSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!--FindTags-->
+ <wsdl:operation name="FindTags">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindTags" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:FindTagsSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:FindTagsSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindTagsResult" use="literal" />
+ <soap:header message="tns:FindTagsSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!--AddTag-->
+ <wsdl:operation name="AddTag">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/AddTag" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:AddTagSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:AddTagSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="AddTagResult" use="literal" />
+ <soap:header message="tns:AddTagSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!--HideTag-->
+ <wsdl:operation name="HideTag">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/HideTag" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:HideTagSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:HideTagSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="HideTagResult" use="literal" />
+ <soap:header message="tns:HideTagSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!--GetPersona-->
+ <wsdl:operation name="GetPersona">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetPersona" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:GetPersonaSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:GetPersonaSoapIn" part="Impersonation" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetPersonaResult" use="literal" />
+ <soap:header message="tns:GetPersonaSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Inbox Rules Operations -->
+
+ <!-- GetInboxRules -->
+ <wsdl:operation name="GetInboxRules">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetInboxRules" />
+ <wsdl:input>
+ <soap:header message="tns:GetInboxRulesSoapIn" part="Impersonation" use="literal" />
+ <soap:header message="tns:GetInboxRulesSoapIn" part="MailboxCulture" use="literal" />
+ <soap:header message="tns:GetInboxRulesSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:GetInboxRulesSoapIn" part="TimeZoneContext" use="literal" />
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetInboxRulesResult" use="literal" />
+ <soap:header message="tns:GetInboxRulesSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- UpdateInboxRules -->
+ <wsdl:operation name="UpdateInboxRules">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateInboxRules" />
+ <wsdl:input>
+ <soap:header message="tns:UpdateInboxRulesSoapIn" part="Impersonation" use="literal" />
+ <soap:header message="tns:UpdateInboxRulesSoapIn" part="MailboxCulture" use="literal" />
+ <soap:header message="tns:UpdateInboxRulesSoapIn" part="RequestVersion" use="literal" />
+ <soap:header message="tns:UpdateInboxRulesSoapIn" part="TimeZoneContext" use="literal" />
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateInboxRulesResult" use="literal" />
+ <soap:header message="tns:UpdateInboxRulesSoapOut" part="ServerVersion" use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetPasswordExpirationDate">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetPasswordExpirationDate" />
+ <wsdl:input>
+ <soap:header message="tns:GetPasswordExpirationDateSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetPasswordExpirationDateSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetPasswordExpirationDateResult" use="literal" />
+ <soap:header message="tns:GetPasswordExpirationDateSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Mailbox Search Operations -->
+ <!-- GetDiscoverySearchConfiguration -->
+ <wsdl:operation name="GetDiscoverySearchConfiguration">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetDiscoverySearchConfiguration" />
+ <wsdl:input>
+ <soap:header message="tns:GetDiscoverySearchConfigurationSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetDiscoverySearchConfigurationSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetDiscoverySearchConfigurationResult" use="literal" />
+ <soap:header message="tns:GetDiscoverySearchConfigurationSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetSearchableMailboxes -->
+ <wsdl:operation name="GetSearchableMailboxes">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetSearchableMailboxes" />
+ <wsdl:input>
+ <soap:header message="tns:GetSearchableMailboxesSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetSearchableMailboxesSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetSearchableMailboxesResult" use="literal" />
+ <soap:header message="tns:GetSearchableMailboxesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- SearchMailboxes -->
+ <wsdl:operation name="SearchMailboxes">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SearchMailboxes" />
+ <wsdl:input>
+ <soap:header message="tns:SearchMailboxesSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:SearchMailboxesSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SearchMailboxesResult" use="literal" />
+ <soap:header message="tns:SearchMailboxesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetHoldOnMailboxes -->
+ <wsdl:operation name="GetHoldOnMailboxes">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetHoldOnMailboxes" />
+ <wsdl:input>
+ <soap:header message="tns:GetHoldOnMailboxesSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetHoldOnMailboxesSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetHoldOnMailboxesResult" use="literal" />
+ <soap:header message="tns:GetHoldOnMailboxesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- SetHoldOnMailboxes -->
+ <wsdl:operation name="SetHoldOnMailboxes">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SetHoldOnMailboxes" />
+ <wsdl:input>
+ <soap:header message="tns:SetHoldOnMailboxesSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:SetHoldOnMailboxesSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SetHoldOnMailboxesResult" use="literal" />
+ <soap:header message="tns:SetHoldOnMailboxesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetNonIndexableItemStatistics -->
+ <wsdl:operation name="GetNonIndexableItemStatistics">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetNonIndexableItemStatistics" />
+ <wsdl:input>
+ <soap:header message="tns:GetNonIndexableItemStatisticsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetNonIndexableItemStatisticsSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetNonIndexableItemStatisticsResult" use="literal" />
+ <soap:header message="tns:GetNonIndexableItemStatisticsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetNonIndexableItemDetails -->
+ <wsdl:operation name="GetNonIndexableItemDetails">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetNonIndexableItemDetails" />
+ <wsdl:input>
+ <soap:header message="tns:GetNonIndexableItemDetailsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetNonIndexableItemDetailsSoapIn" part="ManagementRole" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetNonIndexableItemDetailsResult" use="literal" />
+ <soap:header message="tns:GetNonIndexableItemDetailsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="MarkAllItemsAsRead">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/MarkAllItemsAsRead" />
+ <wsdl:input>
+ <soap:header message="tns:MarkAllItemsAsReadSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:MarkAllItemsAsReadSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:MarkAllItemsAsReadSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="MarkAllItemsAsReadResult" use="literal" />
+ <soap:header message="tns:MarkAllItemsAsReadSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="MarkAsJunk">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/MarkAsJunk" />
+ <wsdl:input>
+ <soap:header message="tns:MarkAsJunkSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:MarkAsJunkSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:MarkAsJunkSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="MarkAsJunkResult" use="literal" />
+ <soap:header message="tns:MarkAsJunkSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="ReportMessage">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ReportMessage" />
+ <wsdl:input>
+ <soap:header message="tns:ReportMessageSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:ReportMessageSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:ReportMessageSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ReportMessageResult" use="literal" />
+ <soap:header message="tns:ReportMessageSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetAppManifests">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetAppManifests" />
+ <wsdl:input>
+ <soap:header message="tns:GetAppManifestsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetAppManifestsResult" use="literal" />
+ <soap:header message="tns:GetAppManifestsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Unified Contact Store Operations -->
+ <wsdl:operation name="AddNewImContactToGroup">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/AddNewImContactToGroup" />
+ <wsdl:input>
+ <soap:header message="tns:AddNewImContactToGroupSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:AddNewImContactToGroupSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:AddNewImContactToGroupSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="AddNewImContactToGroupResult" use="literal" />
+ <soap:header message="tns:AddNewImContactToGroupSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddNewTelUriContactToGroup">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/AddNewTelUriContactToGroup" />
+ <wsdl:input>
+ <soap:header message="tns:AddNewTelUriContactToGroupSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:AddNewTelUriContactToGroupSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:AddNewTelUriContactToGroupSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="AddNewTelUriContactToGroupResult" use="literal" />
+ <soap:header message="tns:AddNewTelUriContactToGroupSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddImContactToGroup">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/AddImContactToGroup" />
+ <wsdl:input>
+ <soap:header message="tns:AddImContactToGroupSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:AddImContactToGroupSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:AddImContactToGroupSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="AddImContactToGroupResult" use="literal" />
+ <soap:header message="tns:AddImContactToGroupSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveImContactFromGroup">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/RemoveImContactFromGroup" />
+ <wsdl:input>
+ <soap:header message="tns:RemoveImContactFromGroupSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:RemoveImContactFromGroupSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:RemoveImContactFromGroupSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="RemoveImContactFromGroupResult" use="literal" />
+ <soap:header message="tns:RemoveImContactFromGroupSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddImGroup">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/AddImGroup" />
+ <wsdl:input>
+ <soap:header message="tns:AddImGroupSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:AddImGroupSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:AddImGroupSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="AddImGroupResult" use="literal" />
+ <soap:header message="tns:AddImGroupSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="AddDistributionGroupToImList">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/AddDistributionGroupToImList" />
+ <wsdl:input>
+ <soap:header message="tns:AddDistributionGroupToImListSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:AddDistributionGroupToImListSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:AddDistributionGroupToImListSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="AddDistributionGroupToImListResult" use="literal" />
+ <soap:header message="tns:AddDistributionGroupToImListSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetImItemList">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetImItemList" />
+ <wsdl:input>
+ <soap:header message="tns:GetImItemListSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetImItemListSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetImItemListSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetImItemListResult" use="literal" />
+ <soap:header message="tns:GetImItemListSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetImItems">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetImItems" />
+ <wsdl:input>
+ <soap:header message="tns:GetImItemsSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:GetImItemsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:GetImItemsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetImItemsResult" use="literal" />
+ <soap:header message="tns:GetImItemsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveContactFromImList">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/RemoveContactFromImList" />
+ <wsdl:input>
+ <soap:header message="tns:RemoveContactFromImListSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:RemoveContactFromImListSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:RemoveContactFromImListSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="RemoveContactFromImListResult" use="literal" />
+ <soap:header message="tns:RemoveContactFromImListSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveDistributionGroupFromImList">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/RemoveDistributionGroupFromImList" />
+ <wsdl:input>
+ <soap:header message="tns:RemoveDistributionGroupFromImListSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:RemoveDistributionGroupFromImListSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:RemoveDistributionGroupFromImListSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="RemoveDistributionGroupFromImListResult" use="literal" />
+ <soap:header message="tns:RemoveDistributionGroupFromImListSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="RemoveImGroup">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/RemoveImGroup" />
+ <wsdl:input>
+ <soap:header message="tns:RemoveImGroupSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:RemoveImGroupSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:RemoveImGroupSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="RemoveImGroupResult" use="literal" />
+ <soap:header message="tns:RemoveImGroupSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="SetImGroup">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SetImGroup" />
+ <wsdl:input>
+ <soap:header message="tns:SetImGroupSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:SetImGroupSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:SetImGroupSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SetImGroupResult" use="literal" />
+ <soap:header message="tns:SetImGroupSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="SetImListMigrationCompleted">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SetImListMigrationCompleted" />
+ <wsdl:input>
+ <soap:header message="tns:SetImListMigrationCompletedSoapIn" part="Impersonation" use="literal"/>
+ <soap:header message="tns:SetImListMigrationCompletedSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:header message="tns:SetImListMigrationCompletedSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SetImListMigrationCompletedResult" use="literal" />
+ <soap:header message="tns:SetImListMigrationCompletedSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- MRM Operations -->
+
+ <!-- GetRetentionPolicyTags -->
+ <wsdl:operation name="GetUserRetentionPolicyTags">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetUserRetentionPolicyTags" />
+ <wsdl:input>
+ <soap:header message="tns:GetUserRetentionPolicyTagsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetUserRetentionPolicyTagsResult" use="literal" />
+ <soap:header message="tns:GetUserRetentionPolicyTagsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="DisableApp">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DisableApp"/>
+ <wsdl:input>
+ <soap:header message="tns:DisableAppSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DisableAppResult" use="literal"/>
+ <soap:header message="tns:DisableAppSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="InstallApp">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/InstallApp"/>
+ <wsdl:input>
+ <soap:header message="tns:InstallAppSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="InstallAppResult" use="literal"/>
+ <soap:header message="tns:InstallAppSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="UninstallApp">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UninstallApp"/>
+ <wsdl:input>
+ <soap:header message="tns:UninstallAppSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UninstallAppResult" use="literal"/>
+ <soap:header message="tns:UninstallAppSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetAppMarketplaceUrl">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetAppMarketplaceUrl"/>
+ <wsdl:input>
+ <soap:header message="tns:GetAppMarketplaceUrlSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetAppMarketplaceUrlResult" use="literal"/>
+ <soap:header message="tns:GetAppMarketplaceUrlSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- FindAvailableMeetingTimes (Binding) Operation -->
+ <wsdl:operation name="FindAvailableMeetingTimes">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindAvailableMeetingTimes" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:FindAvailableMeetingTimesSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindAvailableMeetingTimesResult" use="literal" />
+ <soap:header message="tns:FindAvailableMeetingTimesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- FindMeetingTimeCandidates (Binding) Operation -->
+ <wsdl:operation name="FindMeetingTimeCandidates">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindMeetingTimeCandidates" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:FindMeetingTimeCandidatesSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindMeetingTimeCandidatesResult" use="literal" />
+ <soap:header message="tns:FindMeetingTimeCandidatesSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Photos -->
+ <wsdl:operation name="GetUserPhoto">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetUserPhoto"/>
+ <wsdl:input>
+ <soap:header message="tns:GetUserPhotoSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetUserPhotoResult" use="literal"/>
+ <soap:header message="tns:GetUserPhotoSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="SetUserPhoto">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/SetUserPhoto"/>
+ <wsdl:input>
+ <soap:header message="tns:SetUserPhotoSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="SetUserPhotoResult" use="literal"/>
+ <soap:header message="tns:SetUserPhotoSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetMeetingSpace">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetMeetingSpace" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:GetMeetingSpaceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetMeetingSpaceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetMeetingSpaceResult" use="literal" />
+ <soap:header message="tns:GetMeetingSpaceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="DeleteMeetingSpace">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DeleteMeetingSpace" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:DeleteMeetingSpaceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:DeleteMeetingSpaceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DeleteMeetingSpaceResult" use="literal" />
+ <soap:header message="tns:DeleteMeetingSpaceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="UpdateMeetingSpace">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateMeetingSpace" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:UpdateMeetingSpaceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:UpdateMeetingSpaceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateMeetingSpaceResult" use="literal" />
+ <soap:header message="tns:UpdateMeetingSpaceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateMeetingSpace">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateMeetingSpace" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:CreateMeetingSpaceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:CreateMeetingSpaceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateMeetingSpaceResult" use="literal" />
+ <soap:header message="tns:CreateMeetingSpaceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="FindMeetingSpaceByJoinUrl">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/FindMeetingSpaceByJoinUrl" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:FindMeetingSpaceByJoinUrlSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:FindMeetingSpaceByJoinUrlSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="FindMeetingSpaceByJoinUrlResult" use="literal" />
+ <soap:header message="tns:FindMeetingSpaceByJoinUrlSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="GetMeetingInstance">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetMeetingInstanceRequest" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:GetMeetingInstanceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetMeetingInstanceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetMeetingInstanceResult" use="literal" />
+ <soap:header message="tns:GetMeetingInstanceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="DeleteMeetingInstance">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DeleteMeetingInstanceRequest" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:DeleteMeetingInstanceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:DeleteMeetingInstanceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DeleteMeetingInstanceResult" use="literal" />
+ <soap:header message="tns:DeleteMeetingInstanceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="UpdateMeetingInstance">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/UpdateMeetingInstanceRequest" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:UpdateMeetingInstanceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:UpdateMeetingInstanceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="UpdateMeetingInstanceResult" use="literal" />
+ <soap:header message="tns:UpdateMeetingInstanceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <wsdl:operation name="CreateMeetingInstance">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/CreateMeetingInstanceRequest" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:CreateMeetingInstanceSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:CreateMeetingInstanceSoapIn" part="ManagementRole" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="CreateMeetingInstanceResult" use="literal" />
+ <soap:header message="tns:CreateMeetingInstanceSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Start Search Session -->
+ <wsdl:operation name="StartSearchSession">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/StartSearchSession" />
+ <wsdl:input>
+ <soap:header message="tns:StartSearchSessionSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:StartSearchSessionSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="StartSearchSessionResult" use="literal" />
+ <soap:header message="tns:StartSearchSessionSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Execute Search -->
+ <wsdl:operation name="ExecuteSearch">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/ExecuteSearch" />
+ <wsdl:input>
+ <soap:header message="tns:ExecuteSearchSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:ExecuteSearchSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="ExecuteSearchResult" use="literal" />
+ <soap:header message="tns:ExecuteSearchSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Get SearchSuggestions -->
+ <wsdl:operation name="GetSearchSuggestions">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetSearchSuggestions" />
+ <wsdl:input>
+ <soap:header message="tns:GetSearchSuggestionsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:GetSearchSuggestionsSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetSearchSuggestionsResult" use="literal" />
+ <soap:header message="tns:GetSearchSuggestionsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- Delete SearchSuggestion -->
+ <wsdl:operation name="DeleteSearchSuggestion">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/DeleteSearchSuggestion" />
+ <wsdl:input>
+ <soap:header message="tns:DeleteSearchSuggestionSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:DeleteSearchSuggestionSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="DeleteSearchSuggestionResult" use="literal" />
+ <soap:header message="tns:DeleteSearchSuggestionSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- End Search Session-->
+ <wsdl:operation name="EndSearchSession">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/EndSearchSession" />
+ <wsdl:input>
+ <soap:header message="tns:EndSearchSessionSoapIn" part="RequestVersion" use="literal"/>
+ <soap:header message="tns:EndSearchSessionSoapIn" part="MailboxCulture" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="EndSearchSessionResult" use="literal" />
+ <soap:header message="tns:EndSearchSessionSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetLastPrivateCatalogUpdate (Binding) Operation -->
+ <wsdl:operation name="GetLastPrivateCatalogUpdate">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetLastPrivateCatalogUpdate" />
+ <wsdl:input>
+ <soap:body parts="request" use="literal" />
+ <soap:header message="tns:GetLastPrivateCatalogUpdateSoapIn" part="RequestVersion" use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetLastPrivateCatalogUpdateResult" use="literal" />
+ <soap:header message="tns:GetLastPrivateCatalogUpdateSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+
+ <!-- GetPrivateCatalogAddIns (Binding) Operation -->
+ <wsdl:operation name="GetPrivateCatalogAddIns">
+ <soap:operation soapAction="http://schemas.microsoft.com/exchange/services/2006/messages/GetPrivateCatalogAddIns" />
+ <wsdl:input>
+ <soap:header message="tns:GetPrivateCatalogAddInsSoapIn" part="RequestVersion" use="literal"/>
+ <soap:body parts="request" use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body parts="GetPrivateCatalogAddInsResult" use="literal" />
+ <soap:header message="tns:GetPrivateCatalogAddInsSoapOut" part="ServerVersion" use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+
+ <wsdl:service name="ExchangeServices">
+ <wsdl:port name="ExchangeServicePort" binding="tns:ExchangeServiceBinding">
+ <soap:address location="" />
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/types.xsd b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/types.xsd
new file mode 100644
index 00000000..52f4f189
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/assets/types.xsd
@@ -0,0 +1,9779 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xs:schema id="types"
+ elementFormDefault="qualified"
+ xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
+ targetNamespace="http://schemas.microsoft.com/exchange/services/2006/types"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
+
+ <!-- SOAP header to indicate language for mailbox interaction-->
+ <xs:complexType name="MailboxCultureType">
+ <xs:simpleContent>
+ <xs:extension base="xs:language">
+ <xs:anyAttribute namespace="http://schemas.xmlsoap.org/soap/envelope/">
+ <xs:annotation>
+ <xs:documentation>Allow attributes in the soap namespace to be used here</xs:documentation>
+ </xs:annotation>
+ </xs:anyAttribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="MailboxCulture" type="t:MailboxCultureType"/>
+
+ <xs:complexType name="InstalledAppType">
+ <xs:sequence minOccurs="0">
+ <xs:element name="Id" type="xs:string" minOccurs="0"/>
+ <xs:element name="MarketplaceAssetId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Enabled" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ConsentState" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Type" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LicenseStatus" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="TrialExpirationDate" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ProviderName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IconUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="HighResolutionIconUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Requirements" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Version" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- SOAP header to indicate which roles the caller or application want to use -->
+ <xs:complexType name="NonEmptyArrayOfRoleType">
+ <xs:sequence>
+ <xs:element name="Role" type="xs:string" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ManagementRoleType">
+ <xs:sequence>
+ <xs:element name="UserRoles" type="t:NonEmptyArrayOfRoleType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ApplicationRoles" type="t:NonEmptyArrayOfRoleType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="ManagementRole" type="t:ManagementRoleType" />
+
+ <!-- Server to Server auth SOAP header information -->
+ <xs:complexType name="SidAndAttributesType">
+ <xs:sequence>
+ <xs:element name="SecurityIdentifier" type="xs:string"/>
+ </xs:sequence>
+ <xs:attribute name="Attributes" type="xs:unsignedInt" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfGroupIdentifiersType">
+ <xs:sequence>
+ <xs:element name="GroupIdentifier" type="t:SidAndAttributesType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfRestrictedGroupIdentifiersType">
+ <xs:sequence>
+ <xs:element name="RestrictedGroupIdentifier" type="t:SidAndAttributesType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SerializedSecurityContextType">
+ <xs:sequence>
+ <xs:element name="UserSid" type="xs:string"/>
+ <xs:element name="GroupSids" type="t:NonEmptyArrayOfGroupIdentifiersType" minOccurs="0"/>
+ <xs:element name="RestrictedGroupSids" type="t:NonEmptyArrayOfRestrictedGroupIdentifiersType" minOccurs="0"/>
+ <xs:element name="PrimarySmtpAddress" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="http://schemas.xmlsoap.org/soap/envelope/">
+ <xs:annotation>
+ <xs:documentation>Allow attributes in the soap namespace to be used here</xs:documentation>
+ </xs:annotation>
+ </xs:anyAttribute>
+ </xs:complexType>
+ <xs:element name="SerializedSecurityContext" type="t:SerializedSecurityContextType"/>
+
+ <xs:complexType name="ConnectingSIDType">
+ <xs:choice>
+ <xs:element name="PrincipalName" type="t:PrincipalNameType" />
+ <xs:element name="SID" type="t:SIDType" />
+ <xs:element name="PrimarySmtpAddress" type="t:PrimarySmtpAddressType" />
+ <xs:element name="SmtpAddress" type="t:SmtpAddressType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="PrincipalNameType">
+ <xs:simpleContent>
+ <xs:extension base="t:NonEmptyStringType" />
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="SIDType">
+ <xs:simpleContent>
+ <xs:extension base="t:NonEmptyStringType" />
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="PrimarySmtpAddressType">
+ <xs:simpleContent>
+ <xs:extension base="t:NonEmptyStringType" />
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="SmtpAddressType">
+ <xs:simpleContent>
+ <xs:extension base="t:NonEmptyStringType" />
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="ExchangeImpersonationType">
+ <xs:sequence>
+ <xs:element name="ConnectingSID" type="t:ConnectingSIDType" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="http://schemas.xmlsoap.org/soap/envelope/">
+ <xs:annotation>
+ <xs:documentation>Allow attributes in the soap namespace to be used here</xs:documentation>
+ </xs:annotation>
+ </xs:anyAttribute>
+ </xs:complexType>
+ <xs:element name="ExchangeImpersonation" type="t:ExchangeImpersonationType" />
+
+ <xs:simpleType name="SpecialLogonTypeType">
+ <xs:annotation>
+ <xs:documentation>Surfaces the various logon types that are supported for conversion</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Admin"/>
+ <xs:enumeration value="SystemService"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="OpenAsAdminOrSystemServiceType">
+ <xs:sequence>
+ <xs:element name="ConnectingSID" type="t:ConnectingSIDType" />
+ </xs:sequence>
+ <xs:attribute name="LogonType" type="t:SpecialLogonTypeType" use="required"/>
+ <xs:attribute name="BudgetType" type="xs:int" use="optional"/>
+ <xs:anyAttribute namespace="http://schemas.xmlsoap.org/soap/envelope/">
+ <xs:annotation>
+ <xs:documentation>Allow attributes in the soap namespace to be used here</xs:documentation>
+ </xs:annotation>
+ </xs:anyAttribute>
+ </xs:complexType>
+ <xs:element name="OpenAsAdminOrSystemService" type="t:OpenAsAdminOrSystemServiceType" />
+
+ <!-- External sharing security header for person-to-person sharing relationships -->
+ <xs:element name="SharingSecurity" type="t:EncryptedDataContainerType"/>
+
+ <!-- Enumeration of Exchange Server versions -->
+ <xs:simpleType name="ExchangeVersionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Exchange2007" />
+ <xs:enumeration value="Exchange2007_SP1" />
+ <xs:enumeration value="Exchange2009" />
+ <xs:enumeration value="Exchange2010" />
+ <xs:enumeration value="Exchange2010_SP1" />
+ <xs:enumeration value="Exchange2010_SP2" />
+ <xs:enumeration value="Exchange2012" />
+ <xs:enumeration value="Exchange2013" />
+ <xs:enumeration value="Exchange2013_SP1" />
+ <xs:enumeration value="Exchange2015" />
+ <xs:enumeration value="Exchange2016" />
+ <xs:enumeration value="V2015_10_05" />
+ <xs:enumeration value="V2016_01_06" />
+ <xs:enumeration value="V2016_04_13" />
+ <xs:enumeration value="V2016_07_13" />
+ <xs:enumeration value="V2016_10_10" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ProxySecurityContextType">
+ <xs:simpleContent>
+ <xs:extension base="xs:base64Binary">
+ <xs:anyAttribute namespace="http://schemas.xmlsoap.org/soap/envelope/">
+ <xs:annotation>
+ <xs:documentation>Allow attributes in the soap namespace to be used here</xs:documentation>
+ </xs:annotation>
+ </xs:anyAttribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:element name="ProxySecurityContext" type="t:ProxySecurityContextType"/>
+ <xs:element name="ProxySuggesterSid" type="t:ProxySecurityContextType"/>
+ <xs:element name="ProxyPartnerToken" type="t:ProxySecurityContextType" />
+
+ <!-- Used in the SOAP header of responses for diagnostics purposes. -->
+ <xs:element name="ServerVersionInfo">
+ <xs:complexType>
+ <xs:attribute name="MajorVersion" type="xs:int" use="optional"/>
+ <xs:attribute name="MinorVersion" type="xs:int" use="optional"/>
+ <xs:attribute name="MajorBuildNumber" type="xs:int" use="optional"/>
+ <xs:attribute name="MinorBuildNumber" type="xs:int" use="optional"/>
+ <xs:attribute name="Version" type="xs:string" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+
+ <!-- Used in the SOAP header of requests to specify version for request. -->
+ <xs:element name="RequestServerVersion">
+ <xs:complexType>
+ <xs:attribute name="Version" type="t:ExchangeVersionType" use="required"/>
+ <xs:anyAttribute namespace="http://schemas.xmlsoap.org/soap/envelope/">
+ <xs:annotation>
+ <xs:documentation>Allow attributes in the soap namespace to be used here</xs:documentation>
+ </xs:annotation>
+ </xs:anyAttribute>
+ </xs:complexType>
+ </xs:element>
+
+ <!-- DateTimePrecision for Soap header -->
+
+ <xs:simpleType name="DateTimePrecisionType">
+ <xs:annotation>
+ <xs:documentation>Precision for returned DateTime values</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Seconds" />
+ <xs:enumeration value="Milliseconds" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="DateTimePrecision" type="t:DateTimePrecisionType" />
+
+ <!-- Email address/participant types -->
+
+ <xs:simpleType name="NonEmptyStringType">
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="BaseEmailAddressType" />
+
+ <xs:simpleType name="MailboxTypeType">
+ <xs:restriction base="xs:string">
+
+ <xs:enumeration value="Unknown" />
+ <xs:enumeration value="OneOff" />
+
+ <xs:enumeration value="Mailbox" />
+ <xs:enumeration value="PublicDL" />
+
+ <xs:enumeration value="PrivateDL" />
+ <xs:enumeration value="Contact" />
+
+ <xs:enumeration value="PublicFolder" />
+ <xs:enumeration value="GroupMailbox" />
+ <xs:enumeration value="ImplicitContact" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="EmailAddressType">
+ <xs:annotation>
+ <xs:documentation>Identifier for a fully resolved email address</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BaseEmailAddressType">
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="0"/>
+ <xs:element name="EmailAddress" type="t:NonEmptyStringType" minOccurs="0"/>
+ <xs:element name="RoutingType" type="t:NonEmptyStringType" minOccurs="0"/>
+ <xs:element name="MailboxType" type="t:MailboxTypeType" minOccurs="0" />
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="0" />
+ <xs:element name="OriginalDisplayName" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="EmailAddressExtendedType">
+ <xs:annotation>
+ <xs:documentation>Extends EmailAddress by adding the external object id</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:EmailAddressType">
+ <xs:sequence>
+ <xs:element name="ExternalObjectId" type="xs:string" minOccurs="0"/>
+ <xs:element name="PrimaryEmailAddress" type="t:NonEmptyStringType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- GetRooms Service Types -->
+
+ <xs:complexType name="ArrayOfEmailAddressesType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="Address" type="t:EmailAddressType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DirectoryEntryType">
+ <xs:sequence>
+ <xs:element name="Id" type="t:EmailAddressType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="RoomType">
+ <xs:complexContent>
+ <xs:extension base="t:DirectoryEntryType">
+ <!-- We don't need anything additional at this time -->
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRoomsType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="Room" type="t:RoomType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- FindAvailableMeetingTimes Service Types -->
+
+ <xs:complexType name="TimeSlot">
+ <xs:sequence>
+ <xs:element name="StartTime" type="xs:dateTime" />
+ <xs:element name="DurationInMinutes" type="xs:double" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingLocation">
+ <xs:sequence>
+ <xs:element name="EmailAddress" type="xs:string" />
+ <xs:element name="DisplayName" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="ActivityDomainType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Unknown" />
+ <xs:enumeration value="Personal" />
+ <xs:enumeration value="Work" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- GetReminders Service Types -->
+
+ <xs:simpleType name="ReminderGroupType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Calendar" />
+ <xs:enumeration value="Task" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ReminderType">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="Subject" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Location" type="xs:string" />
+ <xs:element minOccurs="1" maxOccurs="1" name="ReminderTime" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="StartDate" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="EndDate" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="ItemId" type="t:ItemIdType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="RecurringMasterItemId" type="t:ItemIdType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="ReminderGroup" type="t:ReminderGroupType" />
+ <xs:element minOccurs="1" maxOccurs="1" name="UID" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRemindersType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="Reminder" type="t:ReminderType" />
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <!-- - - - - - - - - - - - - - - - - - - -->
+ <!-- Recipient List -->
+ <!-- - - - - - - - - - - - - - - - - - - -->
+ <xs:complexType name="ArrayOfRecipientsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Mailbox" type="t:EmailAddressType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="SingleRecipientType">
+ <xs:choice>
+ <xs:element name="Mailbox" type="t:EmailAddressType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- URIs for frequently referenced types -->
+ <xs:simpleType name="UnindexedFieldURIType">
+ <xs:restriction base="xs:string">
+
+ <!-- Folder fields -->
+
+ <xs:enumeration value="folder:FolderId"/>
+ <xs:enumeration value="folder:ParentFolderId"/>
+ <xs:enumeration value="folder:DisplayName" />
+ <xs:enumeration value="folder:UnreadCount" />
+ <xs:enumeration value="folder:TotalCount" />
+ <xs:enumeration value="folder:ChildFolderCount" />
+ <xs:enumeration value="folder:FolderClass" />
+ <xs:enumeration value="folder:SearchParameters"/>
+ <xs:enumeration value="folder:ManagedFolderInformation"/>
+ <xs:enumeration value="folder:PermissionSet"/>
+ <xs:enumeration value="folder:EffectiveRights"/>
+ <xs:enumeration value="folder:SharingEffectiveRights"/>
+ <xs:enumeration value="folder:DistinguishedFolderId"/>
+ <xs:enumeration value="folder:PolicyTag"/>
+ <xs:enumeration value="folder:ArchiveTag"/>
+ <xs:enumeration value="folder:ReplicaList"/>
+
+ <!-- Item fields -->
+
+ <xs:enumeration value="item:ItemId"/>
+ <xs:enumeration value="item:ParentFolderId"/>
+ <xs:enumeration value="item:ItemClass" />
+ <xs:enumeration value="item:MimeContent"/>
+ <xs:enumeration value="item:Attachments" />
+ <xs:enumeration value="item:Subject" />
+ <xs:enumeration value="item:DateTimeReceived" />
+ <xs:enumeration value="item:Size" />
+ <xs:enumeration value="item:Categories" />
+ <xs:enumeration value="item:HasAttachments"/>
+ <xs:enumeration value="item:Importance"/>
+ <xs:enumeration value="item:InReplyTo"/>
+ <xs:enumeration value="item:InternetMessageHeaders" />
+ <xs:enumeration value="item:IsAssociated" />
+ <xs:enumeration value="item:IsDraft" />
+ <xs:enumeration value="item:IsFromMe" />
+ <xs:enumeration value="item:IsResend" />
+ <xs:enumeration value="item:IsSubmitted" />
+ <xs:enumeration value="item:IsUnmodified" />
+ <xs:enumeration value="item:DateTimeSent" />
+ <xs:enumeration value="item:DateTimeCreated" />
+ <xs:enumeration value="item:Body" />
+ <xs:enumeration value="item:ResponseObjects"/>
+ <xs:enumeration value="item:Sensitivity"/>
+
+ <xs:enumeration value="item:ReminderDueBy"/>
+ <xs:enumeration value="item:ReminderIsSet"/>
+ <xs:enumeration value="item:ReminderNextTime"/>
+ <xs:enumeration value="item:ReminderMinutesBeforeStart"/>
+
+ <xs:enumeration value="item:DisplayTo"/>
+ <xs:enumeration value="item:DisplayCc"/>
+ <xs:enumeration value="item:DisplayBcc"/>
+
+ <xs:enumeration value="item:Culture"/>
+ <xs:enumeration value="item:EffectiveRights"/>
+
+ <xs:enumeration value="item:LastModifiedName"/>
+ <xs:enumeration value="item:LastModifiedTime"/>
+ <xs:enumeration value="item:ConversationId"/>
+ <xs:enumeration value="item:UniqueBody"/>
+ <xs:enumeration value="item:Flag"/>
+ <xs:enumeration value="item:StoreEntryId"/>
+ <xs:enumeration value="item:InstanceKey"/>
+ <xs:enumeration value="item:NormalizedBody"/>
+ <xs:enumeration value="item:EntityExtractionResult" />
+ <xs:enumeration value="item:PolicyTag"/>
+ <xs:enumeration value="item:ArchiveTag"/>
+ <xs:enumeration value="item:RetentionDate"/>
+ <xs:enumeration value="item:Preview" />
+ <xs:enumeration value="item:PredictedActionReasons" />
+ <xs:enumeration value="item:IsClutter" />
+ <xs:enumeration value="item:RightsManagementLicenseData" />
+ <xs:enumeration value="item:BlockStatus" />
+ <xs:enumeration value="item:HasBlockedImages" />
+
+ <xs:enumeration value="item:WebClientReadFormQueryString"/>
+ <xs:enumeration value="item:WebClientEditFormQueryString"/>
+
+ <xs:enumeration value="item:TextBody"/>
+
+ <xs:enumeration value="item:IconIndex"/>
+
+ <xs:enumeration value="item:MimeContentUTF8"/>
+
+ <xs:enumeration value="item:Mentions"/>
+ <xs:enumeration value="item:MentionedMe" />
+ <xs:enumeration value="item:MentionsPreview"/>
+ <xs:enumeration value="item:MentionsEx"/>
+ <xs:enumeration value="item:Hashtags"/>
+ <xs:enumeration value="item:AppliedHashtags"/>
+ <xs:enumeration value="item:AppliedHashtagsPreview"/>
+ <xs:enumeration value="item:Likes"/>
+ <xs:enumeration value="item:LikesPreview"/>
+ <xs:enumeration value="item:PendingSocialActivityTagIds"/>
+ <xs:enumeration value="item:AtAllMention"/>
+ <xs:enumeration value="item:CanDelete"/>
+ <xs:enumeration value="item:InferenceClassification"/>
+
+ <xs:enumeration value="item:FirstBody"/>
+
+ <!-- Messages -->
+
+ <xs:enumeration value="message:ConversationIndex"/>
+ <xs:enumeration value="message:ConversationTopic"/>
+ <xs:enumeration value="message:InternetMessageId"/>
+ <xs:enumeration value="message:IsRead"/>
+ <xs:enumeration value="message:IsResponseRequested"/>
+ <xs:enumeration value="message:IsReadReceiptRequested"/>
+ <xs:enumeration value="message:IsDeliveryReceiptRequested"/>
+ <xs:enumeration value="message:ReceivedBy"/>
+ <xs:enumeration value="message:ReceivedRepresenting"/>
+ <xs:enumeration value="message:References"/>
+ <xs:enumeration value="message:ReplyTo"/>
+ <xs:enumeration value="message:From" />
+ <xs:enumeration value="message:Sender" />
+ <xs:enumeration value="message:ToRecipients" />
+ <xs:enumeration value="message:CcRecipients" />
+ <xs:enumeration value="message:BccRecipients" />
+ <xs:enumeration value="message:ApprovalRequestData"/>
+ <xs:enumeration value="message:VotingInformation"/>
+ <xs:enumeration value="message:ReminderMessageData"/>
+
+ <!-- Meeting Message -->
+
+ <xs:enumeration value="meeting:AssociatedCalendarItemId"/>
+ <xs:enumeration value="meeting:IsDelegated"/>
+ <xs:enumeration value="meeting:IsOutOfDate"/>
+ <xs:enumeration value="meeting:HasBeenProcessed"/>
+ <xs:enumeration value="meeting:ResponseType"/>
+
+ <xs:enumeration value="meeting:ProposedStart"/>
+ <xs:enumeration value="meeting:ProposedEnd"/>
+
+ <!-- Meeting Request -->
+
+ <xs:enumeration value="meetingRequest:MeetingRequestType"/>
+ <xs:enumeration value="meetingRequest:IntendedFreeBusyStatus"/>
+ <xs:enumeration value="meetingRequest:ChangeHighlights"/>
+
+ <!-- Calendar items and appointments -->
+
+ <xs:enumeration value="calendar:Start"/>
+ <xs:enumeration value="calendar:End"/>
+ <xs:enumeration value="calendar:OriginalStart"/>
+ <xs:enumeration value="calendar:StartWallClock"/>
+ <xs:enumeration value="calendar:EndWallClock"/>
+ <xs:enumeration value="calendar:StartTimeZoneId"/>
+ <xs:enumeration value="calendar:EndTimeZoneId"/>
+ <xs:enumeration value="calendar:IsAllDayEvent"/>
+ <xs:enumeration value="calendar:LegacyFreeBusyStatus"/>
+ <xs:enumeration value="calendar:Location"/>
+ <xs:enumeration value="calendar:EnhancedLocation"/>
+ <xs:enumeration value="calendar:When"/>
+ <xs:enumeration value="calendar:IsMeeting"/>
+ <xs:enumeration value="calendar:IsCancelled"/>
+ <xs:enumeration value="calendar:IsRecurring"/>
+ <xs:enumeration value="calendar:MeetingRequestWasSent"/>
+ <xs:enumeration value="calendar:IsResponseRequested"/>
+ <xs:enumeration value="calendar:CalendarItemType"/>
+ <xs:enumeration value="calendar:MyResponseType"/>
+ <xs:enumeration value="calendar:Organizer"/>
+ <xs:enumeration value="calendar:RequiredAttendees"/>
+ <xs:enumeration value="calendar:OptionalAttendees"/>
+ <xs:enumeration value="calendar:Resources"/>
+ <xs:enumeration value="calendar:ConflictingMeetingCount"/>
+ <xs:enumeration value="calendar:AdjacentMeetingCount"/>
+ <xs:enumeration value="calendar:ConflictingMeetings"/>
+ <xs:enumeration value="calendar:AdjacentMeetings"/>
+ <xs:enumeration value="calendar:InboxReminders"/>
+
+ <xs:enumeration value="calendar:Duration"/>
+ <xs:enumeration value="calendar:TimeZone"/>
+ <xs:enumeration value="calendar:AppointmentReplyTime"/>
+ <xs:enumeration value="calendar:AppointmentSequenceNumber"/>
+ <xs:enumeration value="calendar:AppointmentState"/>
+
+ <xs:enumeration value="calendar:Recurrence"/>
+ <xs:enumeration value="calendar:FirstOccurrence"/>
+ <xs:enumeration value="calendar:LastOccurrence"/>
+ <xs:enumeration value="calendar:ModifiedOccurrences"/>
+ <xs:enumeration value="calendar:DeletedOccurrences"/>
+ <xs:enumeration value="calendar:MeetingTimeZone"/>
+
+ <xs:enumeration value="calendar:ConferenceType"/>
+ <xs:enumeration value="calendar:AllowNewTimeProposal"/>
+ <xs:enumeration value="calendar:IsOnlineMeeting"/>
+ <xs:enumeration value="calendar:MeetingWorkspaceUrl"/>
+ <xs:enumeration value="calendar:NetShowUrl"/>
+
+ <xs:enumeration value="calendar:UID"/>
+ <xs:enumeration value="calendar:RecurrenceId"/>
+ <xs:enumeration value="calendar:DateTimeStamp"/>
+ <xs:enumeration value="calendar:StartTimeZone"/>
+ <xs:enumeration value="calendar:EndTimeZone"/>
+
+ <xs:enumeration value="calendar:JoinOnlineMeetingUrl"/>
+ <xs:enumeration value="calendar:OnlineMeetingSettings"/>
+
+ <xs:enumeration value="calendar:IsOrganizer"/>
+ <xs:enumeration value="calendar:CalendarActivityData"/>
+
+ <!-- Task properties -->
+
+ <xs:enumeration value="task:ActualWork"/>
+ <xs:enumeration value="task:AssignedTime"/>
+ <xs:enumeration value="task:BillingInformation"/>
+ <xs:enumeration value="task:ChangeCount"/>
+ <xs:enumeration value="task:Companies"/>
+ <xs:enumeration value="task:CompleteDate"/>
+ <xs:enumeration value="task:Contacts"/>
+ <xs:enumeration value="task:DelegationState"/>
+ <xs:enumeration value="task:Delegator"/>
+ <xs:enumeration value="task:DueDate"/>
+ <xs:enumeration value="task:IsAssignmentEditable"/>
+ <xs:enumeration value="task:IsComplete"/>
+ <xs:enumeration value="task:IsRecurring"/>
+ <xs:enumeration value="task:IsTeamTask"/>
+ <xs:enumeration value="task:Mileage"/>
+ <xs:enumeration value="task:Owner"/>
+ <xs:enumeration value="task:PercentComplete"/>
+ <xs:enumeration value="task:Recurrence"/>
+ <xs:enumeration value="task:StartDate"/>
+ <xs:enumeration value="task:Status"/>
+ <xs:enumeration value="task:StatusDescription"/>
+ <xs:enumeration value="task:TotalWork"/>
+
+ <!-- Contacts -->
+
+ <xs:enumeration value="contacts:Alias" />
+ <xs:enumeration value="contacts:AssistantName" />
+ <xs:enumeration value="contacts:Birthday" />
+ <xs:enumeration value="contacts:BusinessHomePage" />
+ <xs:enumeration value="contacts:Children" />
+ <xs:enumeration value="contacts:Companies" />
+ <xs:enumeration value="contacts:CompanyName" />
+ <xs:enumeration value="contacts:CompleteName" />
+ <xs:enumeration value="contacts:ContactSource" />
+ <xs:enumeration value="contacts:Culture" />
+ <xs:enumeration value="contacts:Department" />
+ <xs:enumeration value="contacts:DisplayName" />
+ <xs:enumeration value="contacts:DirectoryId" />
+ <xs:enumeration value="contacts:DirectReports" />
+ <xs:enumeration value="contacts:EmailAddresses" />
+ <xs:enumeration value="contacts:AbchEmailAddresses" />
+ <xs:enumeration value="contacts:FileAs" />
+ <xs:enumeration value="contacts:FileAsMapping" />
+ <xs:enumeration value="contacts:Generation" />
+ <xs:enumeration value="contacts:GivenName" />
+ <xs:enumeration value="contacts:ImAddresses" />
+ <xs:enumeration value="contacts:Initials" />
+ <xs:enumeration value="contacts:JobTitle" />
+ <xs:enumeration value="contacts:Manager" />
+ <xs:enumeration value="contacts:ManagerMailbox" />
+ <xs:enumeration value="contacts:MiddleName" />
+ <xs:enumeration value="contacts:Mileage" />
+ <xs:enumeration value="contacts:MSExchangeCertificate" />
+ <xs:enumeration value="contacts:Nickname" />
+ <xs:enumeration value="contacts:Notes" />
+ <xs:enumeration value="contacts:OfficeLocation" />
+ <xs:enumeration value="contacts:PhoneNumbers" />
+ <xs:enumeration value="contacts:PhoneticFullName" />
+ <xs:enumeration value="contacts:PhoneticFirstName" />
+ <xs:enumeration value="contacts:PhoneticLastName" />
+ <xs:enumeration value="contacts:Photo" />
+ <xs:enumeration value="contacts:PhysicalAddresses" />
+ <xs:enumeration value="contacts:PostalAddressIndex" />
+ <xs:enumeration value="contacts:Profession" />
+ <xs:enumeration value="contacts:SpouseName" />
+ <xs:enumeration value="contacts:Surname" />
+ <xs:enumeration value="contacts:WeddingAnniversary" />
+ <xs:enumeration value="contacts:UserSMIMECertificate" />
+ <xs:enumeration value="contacts:HasPicture" />
+ <xs:enumeration value="contacts:AccountName" />
+ <xs:enumeration value="contacts:IsAutoUpdateDisabled" />
+ <xs:enumeration value="contacts:IsMessengerEnabled" />
+ <xs:enumeration value="contacts:Comment" />
+ <xs:enumeration value="contacts:ContactShortId" />
+ <xs:enumeration value="contacts:ContactType" />
+ <xs:enumeration value="contacts:CreatedBy" />
+ <xs:enumeration value="contacts:Gender" />
+ <xs:enumeration value="contacts:IsHidden" />
+ <xs:enumeration value="contacts:ObjectId" />
+ <xs:enumeration value="contacts:PassportId" />
+ <xs:enumeration value="contacts:IsPrivate" />
+ <xs:enumeration value="contacts:SourceId" />
+ <xs:enumeration value="contacts:TrustLevel" />
+ <xs:enumeration value="contacts:Urls" />
+ <xs:enumeration value="contacts:Cid" />
+ <xs:enumeration value="contacts:SkypeAuthCertificate" />
+ <xs:enumeration value="contacts:SkypeContext" />
+ <xs:enumeration value="contacts:SkypeId" />
+ <xs:enumeration value="contacts:XboxLiveTag" />
+ <xs:enumeration value="contacts:SkypeRelationship" />
+ <xs:enumeration value="contacts:YomiNickname" />
+ <xs:enumeration value="contacts:InviteFree" />
+ <xs:enumeration value="contacts:HidePresenceAndProfile" />
+ <xs:enumeration value="contacts:IsPendingOutbound" />
+ <xs:enumeration value="contacts:SupportGroupFeeds" />
+ <xs:enumeration value="contacts:UserTileHash" />
+ <xs:enumeration value="contacts:UnifiedInbox" />
+ <xs:enumeration value="contacts:Mris" />
+ <xs:enumeration value="contacts:Wlid" />
+ <xs:enumeration value="contacts:AbchContactId" />
+ <xs:enumeration value="contacts:NotInBirthdayCalendar" />
+ <xs:enumeration value="contacts:ShellContactType" />
+ <xs:enumeration value="contacts:ImMri" />
+ <xs:enumeration value="contacts:PresenceTrustLevel" />
+ <xs:enumeration value="contacts:OtherMri" />
+ <xs:enumeration value="contacts:ProfileLastChanged" />
+ <xs:enumeration value="contacts:MobileIMEnabled" />
+ <xs:enumeration value="distributionlist:Members" />
+ <xs:enumeration value="contacts:PartnerNetworkProfilePhotoUrl" />
+ <xs:enumeration value="contacts:PartnerNetworkThumbnailPhotoUrl" />
+ <xs:enumeration value="contacts:PersonId" />
+ <xs:enumeration value="contacts:ConversationGuid" />
+
+ <!-- Post item -->
+ <xs:enumeration value="postitem:PostedTime"/>
+ <!-- Note: The following message Field URIs are also valid for a postitem:
+ message:ConversationIndex
+ message:ConversationTopic
+ message:From
+ message:InternetMessageId
+ message:References
+ message:Sender
+ -->
+
+ <!-- Conversation fields-->
+ <xs:enumeration value ="conversation:ConversationId" />
+ <xs:enumeration value ="conversation:ConversationTopic" />
+ <xs:enumeration value ="conversation:UniqueRecipients" />
+ <xs:enumeration value ="conversation:GlobalUniqueRecipients" />
+ <xs:enumeration value ="conversation:UniqueUnreadSenders" />
+ <xs:enumeration value ="conversation:GlobalUniqueUnreadSenders" />
+ <xs:enumeration value ="conversation:UniqueSenders" />
+ <xs:enumeration value ="conversation:GlobalUniqueSenders" />
+ <xs:enumeration value ="conversation:LastDeliveryTime" />
+ <xs:enumeration value ="conversation:GlobalLastDeliveryTime" />
+ <xs:enumeration value ="conversation:Categories" />
+ <xs:enumeration value ="conversation:GlobalCategories" />
+ <xs:enumeration value ="conversation:FlagStatus" />
+ <xs:enumeration value ="conversation:GlobalFlagStatus" />
+ <xs:enumeration value ="conversation:HasAttachments" />
+ <xs:enumeration value ="conversation:GlobalHasAttachments" />
+ <xs:enumeration value ="conversation:HasIrm" />
+ <xs:enumeration value ="conversation:GlobalHasIrm" />
+ <xs:enumeration value ="conversation:MessageCount" />
+ <xs:enumeration value ="conversation:GlobalMessageCount" />
+ <xs:enumeration value ="conversation:UnreadCount" />
+ <xs:enumeration value ="conversation:GlobalUnreadCount" />
+ <xs:enumeration value ="conversation:Size" />
+ <xs:enumeration value ="conversation:GlobalSize" />
+ <xs:enumeration value ="conversation:ItemClasses" />
+ <xs:enumeration value ="conversation:GlobalItemClasses" />
+ <xs:enumeration value ="conversation:Importance" />
+ <xs:enumeration value ="conversation:GlobalImportance" />
+ <xs:enumeration value ="conversation:ItemIds" />
+ <xs:enumeration value ="conversation:GlobalItemIds" />
+ <xs:enumeration value ="conversation:LastModifiedTime" />
+ <xs:enumeration value ="conversation:InstanceKey" />
+ <xs:enumeration value ="conversation:Preview" />
+ <xs:enumeration value ="conversation:IconIndex" />
+ <xs:enumeration value ="conversation:GlobalIconIndex" />
+ <xs:enumeration value ="conversation:DraftItemIds" />
+ <xs:enumeration value ="conversation:HasClutter" />
+ <xs:enumeration value ="conversation:MentionedMe" />
+ <xs:enumeration value ="conversation:GlobalMentionedMe" />
+ <xs:enumeration value ="conversation:AtAllMention" />
+ <xs:enumeration value ="conversation:GlobalAtAllMention" />
+
+ <!-- Person Insight Fields -->
+ <xs:enumeration value="person:FullName" />
+ <xs:enumeration value="person:GivenName" />
+ <xs:enumeration value="person:Surname" />
+ <xs:enumeration value="person:PhoneNumber" />
+ <xs:enumeration value="person:SMSNumber" />
+ <xs:enumeration value="person:EmailAddress" />
+ <xs:enumeration value="person:Alias" />
+ <xs:enumeration value="person:Department" />
+ <xs:enumeration value="person:LinkedInProfileLink" />
+ <xs:enumeration value="person:Skills" />
+ <xs:enumeration value="person:ProfessionalBiography" />
+ <xs:enumeration value="person:ManagementChain" />
+ <xs:enumeration value="person:DirectReports" />
+ <xs:enumeration value="person:Peers" />
+ <xs:enumeration value="person:TeamSize" />
+ <xs:enumeration value="person:CurrentJob" />
+ <xs:enumeration value="person:Birthday" />
+ <xs:enumeration value="person:Hometown" />
+ <xs:enumeration value="person:CurrentLocation" />
+ <xs:enumeration value="person:CompanyProfile" />
+ <xs:enumeration value="person:Office" />
+ <xs:enumeration value="person:Headline" />
+ <xs:enumeration value="person:MutualConnections" />
+ <xs:enumeration value="person:Title" />
+ <xs:enumeration value="person:MutualManager" />
+ <xs:enumeration value="person:Insights" />
+ <xs:enumeration value="person:UserProfilePicture" />
+
+ <!-- Persona fields-->
+ <xs:enumeration value ="persona:PersonaId" />
+ <xs:enumeration value ="persona:PersonaType" />
+ <xs:enumeration value ="persona:GivenName" />
+ <xs:enumeration value ="persona:CompanyName" />
+ <xs:enumeration value ="persona:Surname" />
+ <xs:enumeration value ="persona:DisplayName" />
+ <xs:enumeration value ="persona:EmailAddress" />
+ <xs:enumeration value ="persona:FileAs" />
+ <xs:enumeration value ="persona:HomeCity" />
+ <xs:enumeration value ="persona:CreationTime" />
+
+
+ <xs:enumeration value ="persona:RelevanceScore" />
+ <xs:enumeration value ="persona:RankingWeight" />
+ <xs:enumeration value ="persona:WorkCity" />
+ <xs:enumeration value ="persona:PersonaObjectStatus" />
+ <xs:enumeration value ="persona:FileAsId" />
+ <xs:enumeration value ="persona:DisplayNamePrefix" />
+ <xs:enumeration value ="persona:YomiCompanyName" />
+ <xs:enumeration value ="persona:YomiFirstName" />
+ <xs:enumeration value ="persona:YomiLastName" />
+ <xs:enumeration value ="persona:Title" />
+ <xs:enumeration value ="persona:EmailAddresses" />
+ <xs:enumeration value ="persona:PhoneNumber" />
+ <xs:enumeration value ="persona:ImAddress" />
+ <xs:enumeration value ="persona:ImAddresses" />
+ <xs:enumeration value ="persona:ImAddresses2" />
+ <xs:enumeration value ="persona:ImAddresses3" />
+ <xs:enumeration value ="persona:FolderIds" />
+ <xs:enumeration value ="persona:Attributions" />
+ <xs:enumeration value ="persona:DisplayNames" />
+ <xs:enumeration value ="persona:Initials" />
+ <xs:enumeration value ="persona:FileAses" />
+ <xs:enumeration value ="persona:FileAsIds" />
+ <xs:enumeration value ="persona:DisplayNamePrefixes" />
+ <xs:enumeration value ="persona:GivenNames" />
+ <xs:enumeration value ="persona:MiddleNames" />
+ <xs:enumeration value ="persona:Surnames" />
+ <xs:enumeration value ="persona:Generations" />
+ <xs:enumeration value ="persona:Nicknames" />
+ <xs:enumeration value ="persona:YomiCompanyNames" />
+ <xs:enumeration value ="persona:YomiFirstNames" />
+ <xs:enumeration value ="persona:YomiLastNames" />
+ <xs:enumeration value ="persona:BusinessPhoneNumbers" />
+ <xs:enumeration value ="persona:BusinessPhoneNumbers2" />
+ <xs:enumeration value ="persona:HomePhones" />
+ <xs:enumeration value ="persona:HomePhones2" />
+ <xs:enumeration value ="persona:MobilePhones" />
+ <xs:enumeration value ="persona:MobilePhones2" />
+ <xs:enumeration value ="persona:AssistantPhoneNumbers" />
+ <xs:enumeration value ="persona:CallbackPhones" />
+ <xs:enumeration value ="persona:CarPhones" />
+ <xs:enumeration value ="persona:HomeFaxes" />
+ <xs:enumeration value ="persona:OrganizationMainPhones" />
+ <xs:enumeration value ="persona:OtherFaxes" />
+ <xs:enumeration value ="persona:OtherTelephones" />
+ <xs:enumeration value ="persona:OtherPhones2" />
+ <xs:enumeration value ="persona:Pagers" />
+ <xs:enumeration value ="persona:RadioPhones" />
+ <xs:enumeration value ="persona:TelexNumbers" />
+ <xs:enumeration value ="persona:WorkFaxes" />
+ <xs:enumeration value ="persona:Emails1" />
+ <xs:enumeration value ="persona:Emails2" />
+ <xs:enumeration value ="persona:Emails3" />
+ <xs:enumeration value ="persona:BusinessHomePages" />
+ <xs:enumeration value ="persona:School" />
+ <xs:enumeration value ="persona:PersonalHomePages" />
+ <xs:enumeration value ="persona:OfficeLocations" />
+ <xs:enumeration value ="persona:BusinessAddresses" />
+ <xs:enumeration value ="persona:HomeAddresses" />
+ <xs:enumeration value ="persona:OtherAddresses" />
+ <xs:enumeration value ="persona:Titles" />
+ <xs:enumeration value ="persona:Departments" />
+ <xs:enumeration value ="persona:CompanyNames" />
+ <xs:enumeration value ="persona:Managers" />
+ <xs:enumeration value ="persona:AssistantNames" />
+ <xs:enumeration value ="persona:Professions" />
+ <xs:enumeration value ="persona:SpouseNames" />
+ <xs:enumeration value ="persona:Hobbies" />
+ <xs:enumeration value ="persona:WeddingAnniversaries" />
+ <xs:enumeration value ="persona:Birthdays" />
+ <xs:enumeration value ="persona:Children" />
+ <xs:enumeration value ="persona:Locations" />
+ <xs:enumeration value ="persona:ExtendedProperties" />
+ <xs:enumeration value ="persona:PostalAddress" />
+ <xs:enumeration value ="persona:Bodies" />
+ <xs:enumeration value ="persona:IsFavorite" />
+ <xs:enumeration value ="persona:InlineLinks" />
+ <xs:enumeration value ="persona:ItemLinkIds" />
+ <xs:enumeration value ="persona:HasActiveDeals" />
+ <xs:enumeration value ="persona:IsBusinessContact" />
+ <xs:enumeration value ="persona:AttributedHasActiveDeals" />
+ <xs:enumeration value ="persona:AttributedIsBusinessContact" />
+ <xs:enumeration value ="persona:SourceMailboxGuids" />
+ <xs:enumeration value ="persona:LastContactedDate" />
+ <xs:enumeration value ="persona:ExternalDirectoryObjectId" />
+ <xs:enumeration value ="persona:MapiEntryId" />
+ <xs:enumeration value ="persona:MapiEmailAddress" />
+ <xs:enumeration value ="persona:MapiAddressType" />
+ <xs:enumeration value ="persona:MapiSearchKey" />
+ <xs:enumeration value ="persona:MapiTransmittableDisplayName" />
+ <xs:enumeration value ="persona:MapiSendRichInfo" />
+
+ <xs:enumeration value="rolemember:MemberType" />
+ <xs:enumeration value="rolemember:MemberId" />
+ <xs:enumeration value="rolemember:DisplayName" />
+
+ <xs:enumeration value="network:TokenRefreshLastCompleted" />
+ <xs:enumeration value="network:TokenRefreshLastAttempted" />
+ <xs:enumeration value="network:SyncEnabled" />
+ <xs:enumeration value="network:RejectedOffers" />
+ <xs:enumeration value="network:SessionHandle" />
+ <xs:enumeration value="network:RefreshTokenExpiry2" />
+ <xs:enumeration value="network:RefreshToken2" />
+ <xs:enumeration value="network:PsaLastChanged" />
+ <xs:enumeration value="network:Offers" />
+ <xs:enumeration value="network:LastWelcomeContact" />
+ <xs:enumeration value="network:LastVersionSaved" />
+ <xs:enumeration value="network:DomainTag" />
+ <xs:enumeration value="network:FirstAuthErrorDates" />
+ <xs:enumeration value="network:ErrorOffers" />
+ <xs:enumeration value="network:ContactSyncSuccess" />
+ <xs:enumeration value="network:ContactSyncError" />
+ <xs:enumeration value="network:ClientToken2" />
+ <xs:enumeration value="network:ClientToken" />
+ <xs:enumeration value="network:ClientPublishSecret" />
+ <xs:enumeration value="network:UserEmail" />
+ <xs:enumeration value="network:AutoLinkSuccess" />
+ <xs:enumeration value="network:AutoLinkError" />
+ <xs:enumeration value="network:IsDefault" />
+ <xs:enumeration value="network:Settings" />
+ <xs:enumeration value="network:ProfileUrl" />
+ <xs:enumeration value="network:UserTileUrl" />
+ <xs:enumeration value="network:DomainId" />
+ <xs:enumeration value="network:DisplayName" />
+ <xs:enumeration value="network:AccountName" />
+ <xs:enumeration value="network:SourceEntryID" />
+
+ <xs:enumeration value="abchperson:FavoriteOrder" />
+ <xs:enumeration value="abchperson:PersonId" />
+ <xs:enumeration value="abchperson:ExchangePersonIdGuid" />
+ <xs:enumeration value="abchperson:AntiLinkInfo" />
+ <xs:enumeration value="abchperson:RelevanceOrder1" />
+ <xs:enumeration value="abchperson:RelevanceOrder2" />
+ <xs:enumeration value="abchperson:ContactHandles" />
+ <xs:enumeration value="abchperson:Categories" />
+
+ <xs:enumeration value="booking:ServiceIds" />
+ <xs:enumeration value="booking:StaffIds" />
+ <xs:enumeration value="booking:StaffInitials" />
+ <xs:enumeration value="booking:CustomerName" />
+ <xs:enumeration value="booking:CustomerEmail" />
+ <xs:enumeration value="booking:CustomerPhone" />
+ <xs:enumeration value="booking:CustomerId" />
+
+ <!--Insight fields-->
+ <xs:enumeration value="insight:InsightId" />
+ <xs:enumeration value="insight:Type" />
+ <xs:enumeration value="insight:StartTimeUtc" />
+ <xs:enumeration value="insight:EndTimeUtc" />
+ <xs:enumeration value="insight:Status" />
+ <xs:enumeration value="insight:Version" />
+ <xs:enumeration value="insight:ApplicationsIds" />
+ <xs:enumeration value="insight:Text" />
+ <xs:enumeration value="insight:SuggestedActions" />
+ <xs:enumeration value="insight:AppContexts" />
+
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="DictionaryURIType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="item:InternetMessageHeader" />
+ <xs:enumeration value="contacts:ImAddress" />
+ <xs:enumeration value="contacts:PhysicalAddress:Street" />
+ <xs:enumeration value="contacts:PhysicalAddress:City" />
+ <xs:enumeration value="contacts:PhysicalAddress:State" />
+ <xs:enumeration value="contacts:PhysicalAddress:CountryOrRegion" />
+ <xs:enumeration value="contacts:PhysicalAddress:PostalCode" />
+ <xs:enumeration value="contacts:PhoneNumber" />
+ <xs:enumeration value="contacts:EmailAddress" />
+
+ <xs:enumeration value="distributionlist:Members:Member" />
+
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- URIs for property types used in MessageXml -->
+ <xs:simpleType name="ExceptionPropertyURIType">
+ <xs:restriction base="xs:string">
+ <!-- Attachment fields -->
+
+ <xs:enumeration value="attachment:Name"/>
+ <xs:enumeration value="attachment:ContentType"/>
+ <xs:enumeration value="attachment:Content" />
+
+ <!-- Recurrence fields -->
+
+ <xs:enumeration value="recurrence:Month"/>
+ <xs:enumeration value="recurrence:DayOfWeekIndex"/>
+ <xs:enumeration value="recurrence:DaysOfWeek" />
+ <xs:enumeration value="recurrence:DayOfMonth"/>
+ <xs:enumeration value="recurrence:Interval" />
+ <xs:enumeration value="recurrence:NumberOfOccurrences" />
+
+ <xs:enumeration value="timezone:Offset" />
+
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- path types -->
+ <xs:simpleType name="GuidType">
+ <xs:annotation>
+ <xs:documentation>
+ The regular expression captures the standard representation of a GUID
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="DistinguishedPropertySetType">
+ <xs:annotation>
+ <xs:documentation>
+ Defines the well known property set ids for extended properties.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Meeting"/>
+ <xs:enumeration value="Appointment"/>
+ <xs:enumeration value="Common"/>
+ <xs:enumeration value="PublicStrings"/>
+ <xs:enumeration value="Address"/>
+ <xs:enumeration value="InternetHeaders"/>
+ <xs:enumeration value="CalendarAssistant"/>
+ <xs:enumeration value="UnifiedMessaging"/>
+ <xs:enumeration value="Task"/>
+ <xs:enumeration value="Sharing" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="MapiPropertyTypeType">
+ <xs:annotation>
+ <xs:documentation>
+ Includes all of the extended property types that we support. Note that Error, Null,
+ Object and Object array can not be used in restrictions, or for setting/getting values.
+ They are only there for error reporting purposes.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ApplicationTime"/>
+ <xs:enumeration value="ApplicationTimeArray"/>
+ <xs:enumeration value="Binary"/>
+ <xs:enumeration value="BinaryArray"/>
+ <xs:enumeration value="Boolean"/>
+ <xs:enumeration value="CLSID"/>
+ <xs:enumeration value="CLSIDArray"/>
+ <xs:enumeration value="Currency"/>
+ <xs:enumeration value="CurrencyArray"/>
+ <xs:enumeration value="Double"/>
+ <xs:enumeration value="DoubleArray"/>
+ <xs:enumeration value="Error"/>
+ <xs:enumeration value="Float"/>
+ <xs:enumeration value="FloatArray"/>
+ <xs:enumeration value="Integer"/>
+ <xs:enumeration value="IntegerArray"/>
+ <xs:enumeration value="Long"/>
+ <xs:enumeration value="LongArray"/>
+ <xs:enumeration value="Null"/>
+ <xs:enumeration value="Object"/>
+ <xs:enumeration value="ObjectArray"/>
+ <xs:enumeration value="Short"/>
+ <xs:enumeration value="ShortArray"/>
+ <xs:enumeration value="SystemTime"/>
+ <xs:enumeration value="SystemTimeArray"/>
+ <xs:enumeration value="String"/>
+ <xs:enumeration value="StringArray"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="BasePathToElementType" abstract="true"/>
+
+ <xs:complexType name="PathToUnindexedFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePathToElementType">
+ <xs:attribute name="FieldURI" type="t:UnindexedFieldURIType" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="PathToIndexedFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePathToElementType">
+ <xs:attribute name="FieldURI" type="t:DictionaryURIType" use="required" />
+ <xs:attribute name="FieldIndex" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="PathToExceptionFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePathToElementType">
+ <xs:attribute name="FieldURI" type="t:ExceptionPropertyURIType" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="PropertyTagType">
+ <xs:annotation>
+ <xs:documentation>
+ This type represents the property tag (MINUS the type part). There are two options
+ for representation:
+ 1. Hex ==> 0x3fa4
+ 2. Decimal ==> 0-65535
+ </xs:documentation>
+ </xs:annotation>
+ <xs:union memberTypes ="xs:unsignedShort">
+ <xs:simpleType id="HexPropertyTagType">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="(0x|0X)[0-9A-Fa-f]{1,4}"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+
+ <xs:complexType name="PathToExtendedFieldType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents an extended property. Note that there are only a couple of valid attribute
+ combinations. Note that all occurrences require the PropertyType attribute.
+
+ 1. (DistinguishedPropertySetId || PropertySetId) + (PropertyName || Property Id)
+ 2. PropertyTag
+
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BasePathToElementType">
+ <xs:attribute name="DistinguishedPropertySetId" type="t:DistinguishedPropertySetType" use="optional"/>
+ <xs:attribute name="PropertySetId" type="t:GuidType" use="optional"/>
+ <xs:attribute name="PropertyTag" type="t:PropertyTagType" use="optional"/>
+ <xs:attribute name="PropertyName" type="xs:string" use="optional"/>
+ <xs:attribute name="PropertyId" type="xs:int" use="optional"/>
+ <xs:attribute name="PropertyType" type="t:MapiPropertyTypeType" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="Path" abstract="true" type="t:BasePathToElementType"/>
+ <xs:element name="FieldURI" type="t:PathToUnindexedFieldType" substitutionGroup="t:Path"/>
+ <xs:element name="IndexedFieldURI" type="t:PathToIndexedFieldType" substitutionGroup="t:Path" />
+ <xs:element name="ExtendedFieldURI" type="t:PathToExtendedFieldType" substitutionGroup="t:Path"/>
+
+ <!-- For errors only, identifies fields that do not have a uri. -->
+ <xs:element name="ExceptionFieldURI" type="t:PathToExceptionFieldType" />
+
+ <!-- Arrays of paths -->
+ <xs:complexType name="NonEmptyArrayOfPathsToElementType">
+ <!-- using choice here so that proxy generator will not flatten the array and thus lose the
+ item element names -->
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- ExtendedProperty value instances -->
+
+ <xs:complexType name="NonEmptyArrayOfPropertyValuesType">
+ <xs:choice>
+ <xs:element name="Value" type="xs:string" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfExtendedPropertyType">
+ <xs:choice>
+ <xs:element name="ExtendedProperty" type="t:ExtendedPropertyType" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ExtendedPropertyType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents an extended property instance (both its path identifier along with its
+ associated value).
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="ExtendedFieldURI" type="t:PathToExtendedFieldType"/>
+ <xs:choice>
+ <xs:element name="Value" type="xs:string"/>
+ <xs:element name="Values" type="t:NonEmptyArrayOfPropertyValuesType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Query Traversal types -->
+ <xs:simpleType name="FolderQueryTraversalType">
+ <xs:annotation>
+ <xs:documentation>Types of sub-tree traversal for deletion and enumeration</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Shallow" />
+ <xs:enumeration value="Deep" />
+ <xs:enumeration value="SoftDeleted" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="SearchFolderTraversalType">
+ <xs:annotation>
+ <xs:documentation>Types of sub-tree traversal for deletion and enumeration</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Shallow" />
+ <xs:enumeration value="Deep" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ItemQueryTraversalType">
+ <xs:annotation>
+ <xs:documentation>Types of sub-tree traversal for deletion and enumeration</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Shallow" />
+ <xs:enumeration value="SoftDeleted" />
+ <xs:enumeration value="Associated" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ConversationQueryTraversalType">
+ <xs:annotation>
+ <xs:documentation>Types of sub-tree traversal for conversations</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Shallow" />
+ <xs:enumeration value="Deep" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Default shape names for response shapes -->
+ <xs:simpleType name="DefaultShapeNamesType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="IdOnly" />
+ <xs:enumeration value="Default" />
+ <xs:enumeration value="AllProperties" />
+ <xs:enumeration value="PcxPeopleSearch" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="BodyTypeResponseType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Best" />
+ <xs:enumeration value="HTML" />
+ <xs:enumeration value="Text" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Placeholder type from which all folder shape properties are to be derived -->
+ <xs:complexType name="FolderResponseShapeType">
+ <xs:sequence>
+ <xs:element name="BaseShape" type="t:DefaultShapeNamesType" />
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfPathsToElementType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ItemResponseShapeType">
+ <xs:sequence>
+ <xs:element name="BaseShape" type="t:DefaultShapeNamesType" />
+ <xs:element name="IncludeMimeContent" type="xs:boolean" minOccurs="0" />
+ <xs:element name="BodyType" type="t:BodyTypeResponseType" minOccurs="0" />
+ <xs:element name="UniqueBodyType" type="t:BodyTypeResponseType" minOccurs="0" />
+ <xs:element name="NormalizedBodyType" type="t:BodyTypeResponseType" minOccurs="0" />
+ <xs:element name="FilterHtmlContent" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ConvertHtmlCodePageToUTF8" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="InlineImageUrlTemplate" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="BlockExternalImages" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AddBlankTargetToLinks" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MaximumBodySize" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfPathsToElementType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AttachmentResponseShapeType">
+ <xs:sequence>
+ <xs:element name="IncludeMimeContent" type="xs:boolean" minOccurs="0" />
+ <xs:element name="BodyType" type="t:BodyTypeResponseType" minOccurs="0" />
+ <xs:element name="FilterHtmlContent" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfPathsToElementType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ConversationResponseShapeType">
+ <xs:sequence>
+ <xs:element name="BaseShape" type="t:DefaultShapeNamesType" />
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfPathsToElementType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PersonaResponseShapeType">
+ <xs:sequence>
+ <xs:element name="BaseShape" type="t:DefaultShapeNamesType" />
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfPathsToElementType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="DisposalType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="HardDelete" />
+ <xs:enumeration value="SoftDelete" />
+ <xs:enumeration value="MoveToDeletedItems" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- auto-conflict resolution levels -->
+ <xs:simpleType name="ConflictResolutionType">
+ <xs:annotation>
+ <xs:documentation>Type of conflict resolution to attempt during update</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NeverOverwrite" />
+ <xs:enumeration value="AutoResolve" />
+ <xs:enumeration value="AlwaysOverwrite" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ClientAccessTokenTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="CallerIdentity" />
+ <xs:enumeration value="ExtensionCallback" />
+ <xs:enumeration value="ScopedToken" />
+ <xs:enumeration value="ExtensionRestApiCallback" />
+ <xs:enumeration value="Connectors" />
+ <xs:enumeration value="Loki" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NonEmptyArrayOfClientAccessTokenRequestsType">
+ <xs:sequence>
+ <xs:element name="TokenRequest" type="t:ClientAccessTokenRequestType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ClientAccessTokenRequestType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" />
+ <xs:element name="TokenType" type="t:ClientAccessTokenTypeType" />
+ <xs:element name="Scope" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ClientAccessTokenType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" />
+ <xs:element name="TokenType" type="t:ClientAccessTokenTypeType" />
+ <xs:element name="TokenValue" type="xs:string"/>
+ <xs:element name="TTL" type="xs:integer"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="ResponseClassType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Success" />
+ <xs:enumeration value="Warning" />
+ <xs:enumeration value="Error" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Core update operations -->
+ <xs:complexType name="ChangeDescriptionType" abstract="true">
+ <!-- This path element needs some explanation. For update operations, only ONE
+ property can be modified within a single request. That single property must be
+ referenced in the Path element. The Item/Folder element in the derived classes
+ can then only hold a single property that is in agreement with the single path
+ element-->
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ItemChangeDescriptionType">
+ <xs:complexContent>
+ <xs:extension base="t:ChangeDescriptionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="FolderChangeDescriptionType">
+ <xs:complexContent>
+ <xs:extension base="t:ChangeDescriptionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SetItemFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemChangeDescriptionType">
+ <xs:choice>
+ <xs:element name="Item" type="t:ItemType"/>
+ <xs:element name="Message" type="t:MessageType"/>
+ <xs:element name="CalendarItem" type="t:CalendarItemType"/>
+ <xs:element name="Contact" type="t:ContactItemType"/>
+ <xs:element name="DistributionList" type="t:DistributionListType"/>
+ <xs:element name="MeetingMessage" type="t:MeetingMessageType"/>
+ <xs:element name="MeetingRequest" type="t:MeetingRequestMessageType"/>
+ <xs:element name="MeetingResponse" type="t:MeetingResponseMessageType"/>
+ <xs:element name="MeetingCancellation" type="t:MeetingCancellationMessageType"/>
+ <xs:element name="Task" type="t:TaskType"/>
+ <xs:element name="PostItem" type="t:PostItemType"/>
+ <xs:element name="RoleMember" type="t:RoleMemberItemType"/>
+ <xs:element name="Network" type="t:NetworkItemType"/>
+ <xs:element name="Person" type="t:AbchPersonItemType"/>
+ </xs:choice>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SetFolderFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:FolderChangeDescriptionType">
+ <xs:choice>
+ <xs:element name="Folder" type="t:FolderType"/>
+ <xs:element name="CalendarFolder" type="t:CalendarFolderType"/>
+ <xs:element name="ContactsFolder" type="t:ContactsFolderType"/>
+ <xs:element name="SearchFolder" type="t:SearchFolderType"/>
+ <xs:element name="TasksFolder" type="t:TasksFolderType"/>
+ </xs:choice>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="DeleteItemFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemChangeDescriptionType">
+ <xs:sequence/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="DeleteFolderFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:FolderChangeDescriptionType">
+ <xs:sequence/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AppendToItemFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemChangeDescriptionType">
+ <xs:choice>
+ <xs:element name="Item" type="t:ItemType"/>
+ <xs:element name="Message" type="t:MessageType"/>
+ <xs:element name="CalendarItem" type="t:CalendarItemType"/>
+ <xs:element name="Contact" type="t:ContactItemType"/>
+ <xs:element name="DistributionList" type="t:DistributionListType"/>
+ <xs:element name="MeetingMessage" type="t:MeetingMessageType"/>
+ <xs:element name="MeetingRequest" type="t:MeetingRequestMessageType"/>
+ <xs:element name="MeetingResponse" type="t:MeetingResponseMessageType"/>
+ <xs:element name="MeetingCancellation" type="t:MeetingCancellationMessageType"/>
+ <xs:element name="Task" type="t:TaskType"/>
+ <xs:element name="PostItem" type="t:PostItemType"/>
+ <xs:element name="RoleMember" type="t:RoleMemberItemType"/>
+ <xs:element name="Network" type="t:NetworkItemType"/>
+ <xs:element name="Person" type="t:AbchPersonItemType"/>
+ </xs:choice>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AppendToFolderFieldType">
+ <xs:complexContent>
+ <xs:extension base="t:FolderChangeDescriptionType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="Folder" type="t:FolderType"/>
+ <xs:element name="CalendarFolder" type="t:CalendarFolderType"/>
+ <xs:element name="ContactsFolder" type="t:ContactsFolderType"/>
+ <xs:element name="SearchFolder" type="t:SearchFolderType"/>
+ <xs:element name="TasksFolder" type="t:TasksFolderType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfItemChangeDescriptionsType">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="AppendToItemField" type="t:AppendToItemFieldType"/>
+ <xs:element name="SetItemField" type="t:SetItemFieldType"/>
+ <xs:element name="DeleteItemField" type="t:DeleteItemFieldType"/>
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="NonEmptyArrayOfFolderChangeDescriptionsType">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="AppendToFolderField" type="t:AppendToFolderFieldType"/>
+ <xs:element name="SetFolderField" type="t:SetFolderFieldType"/>
+ <xs:element name="DeleteFolderField" type="t:DeleteFolderFieldType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- Updating an item. -->
+
+ <xs:complexType name="ItemChangeType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="ItemId" type="t:ItemIdType" />
+ <xs:element name="OccurrenceItemId" type="t:OccurrenceItemIdType"/>
+ <xs:element name="RecurringMasterItemId" type="t:RecurringMasterItemIdType"/>
+ </xs:choice>
+ <xs:element name="Updates" type="t:NonEmptyArrayOfItemChangeDescriptionsType" />
+ <xs:element name="CalendarActivityData" type="t:CalendarActivityDataType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfItemChangesType">
+ <xs:sequence>
+ <xs:element name="ItemChange" type="t:ItemChangeType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Other headers -->
+ <xs:complexType name="InternetHeaderType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="HeaderName" type="xs:string" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfInternetHeadersType">
+ <xs:sequence>
+ <xs:element name="InternetMessageHeader" type="t:InternetHeaderType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfPredictedActionReasonType">
+ <xs:sequence>
+ <xs:element name="PredictedActionReason" type="t:PredictedActionReasonType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Attachments -->
+
+ <!-- This type is used in GetAttachment -->
+ <xs:complexType name="RequestAttachmentIdType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseItemIdType">
+ <xs:attribute name="Id" type="xs:string" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- This type is used in CreateAttachment responses. CreateAttachment modifies the
+ change key of the root item of the created attachment. We have to return that new
+ change key.-->
+ <xs:complexType name="AttachmentIdType">
+ <xs:complexContent>
+ <xs:extension base="t:RequestAttachmentIdType">
+ <xs:attribute name="RootItemId" type="xs:string" use="optional"/>
+ <xs:attribute name="RootItemChangeKey" type="xs:string" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- This type is used solely in DeleteAttachment responses. -->
+ <xs:complexType name="RootItemIdType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseItemIdType">
+ <xs:attribute name="RootItemId" type="xs:string" use="required"/>
+ <xs:attribute name="RootItemChangeKey" type="xs:string" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfRequestAttachmentIdsType">
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="AttachmentId" type="t:RequestAttachmentIdType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="AttachmentType">
+ <xs:sequence>
+ <xs:element name="AttachmentId" type="t:AttachmentIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ContentType" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ContentId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ContentLocation" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AttachmentOriginalUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Size" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LastModifiedTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IsInline" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ItemAttachmentType">
+ <xs:complexContent>
+ <xs:extension base="t:AttachmentType">
+ <xs:choice minOccurs="0" maxOccurs="1">
+ <xs:element name="Item" type="t:ItemType"/>
+ <xs:element name="Message" type="t:MessageType"/>
+ <xs:element name="CalendarItem" type="t:CalendarItemType"/>
+ <xs:element name="Contact" type="t:ContactItemType"/>
+ <xs:element name="MeetingMessage" type="t:MeetingMessageType"/>
+ <xs:element name="MeetingRequest" type="t:MeetingRequestMessageType"/>
+ <xs:element name="MeetingResponse" type="t:MeetingResponseMessageType"/>
+ <xs:element name="MeetingCancellation" type="t:MeetingCancellationMessageType"/>
+ <xs:element name="Task" type="t:TaskType"/>
+ <xs:element name="PostItem" type="t:PostItemType"/>
+ <xs:element name="RoleMember" type="t:RoleMemberItemType"/>
+ <xs:element name="Network" type="t:NetworkItemType"/>
+ <xs:element name="Person" type="t:AbchPersonItemType"/>
+ </xs:choice>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SyncFolderItemsCreateOrUpdateType">
+ <xs:choice>
+ <xs:element name="Item" type="t:ItemType"/>
+ <xs:element name="Message" type="t:MessageType"/>
+ <xs:element name="CalendarItem" type="t:CalendarItemType"/>
+ <xs:element name="Contact" type="t:ContactItemType"/>
+ <xs:element name="DistributionList" type="t:DistributionListType"/>
+ <xs:element name="MeetingMessage" type="t:MeetingMessageType"/>
+ <xs:element name="MeetingRequest" type="t:MeetingRequestMessageType"/>
+ <xs:element name="MeetingResponse" type="t:MeetingResponseMessageType"/>
+ <xs:element name="MeetingCancellation" type="t:MeetingCancellationMessageType"/>
+ <xs:element name="Task" type="t:TaskType"/>
+ <xs:element name="PostItem" type="t:PostItemType"/>
+ <xs:element name="RoleMember" type="t:RoleMemberItemType"/>
+ <xs:element name="Network" type="t:NetworkItemType"/>
+ <xs:element name="Person" type="t:AbchPersonItemType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="FileAttachmentType">
+ <xs:complexContent>
+ <xs:extension base="t:AttachmentType">
+ <xs:sequence>
+ <xs:element name="IsContactPhoto" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Content" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ReferenceAttachmentType">
+ <xs:complexContent>
+ <xs:extension base="t:AttachmentType">
+ <xs:sequence>
+ <xs:element name="AttachLongPathName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ProviderType" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ProviderEndpointUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AttachmentThumbnailUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AttachmentPreviewUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="PermissionType" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="OriginalPermissionType" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AttachmentIsFolder" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfAttachmentsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="ItemAttachment" type="t:ItemAttachmentType"/>
+ <xs:element name="FileAttachment" type="t:FileAttachmentType"/>
+ <xs:element name="ReferenceAttachment" type="t:ReferenceAttachmentType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfAttachmentsType">
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="ItemAttachment" type="t:ItemAttachmentType"/>
+ <xs:element name="FileAttachment" type="t:FileAttachmentType"/>
+ <xs:element name="ReferenceAttachment" type="t:ReferenceAttachmentType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- Sensitivity enumeration -->
+ <xs:simpleType name="SensitivityChoicesType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Normal" />
+ <xs:enumeration value="Personal" />
+ <xs:enumeration value="Private" />
+ <xs:enumeration value="Confidential" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Importance enumeration -->
+ <xs:simpleType name="ImportanceChoicesType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Low" />
+ <xs:enumeration value="Normal" />
+ <xs:enumeration value="High" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Type of body returned -->
+ <xs:simpleType name="BodyTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="HTML" />
+ <xs:enumeration value="Text" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Body content with body type attribute -->
+ <xs:complexType name="BodyType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="BodyType" type="t:BodyTypeType" use="required" />
+ <xs:attribute name="IsTruncated" type="xs:boolean" use="optional" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- UniqueBody content with body type attribute -->
+ <xs:complexType name="UniqueBodyType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="UniqueBodyType" type="t:BodyTypeType" use="required" />
+ <xs:attribute name="IsTruncated" type="xs:boolean" use="optional" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- NormalizedBody content with body type attribute -->
+ <xs:complexType name="NormalizedBodyType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="NormalizedBodyType" type="t:BodyTypeType" use="required" />
+ <xs:attribute name="IsTruncated" type="xs:boolean" use="optional" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Folder Service types. -->
+ <!-- Folder Ids -->
+ <xs:complexType name="BaseFolderIdType" abstract="true">
+ <xs:annotation>
+ <xs:documentation>Utility type which should never appear in user documents</xs:documentation>
+ </xs:annotation>
+ </xs:complexType>
+
+ <!-- Folder classes -->
+ <xs:simpleType name="FolderClassType">
+ <xs:restriction base="xs:string" />
+ </xs:simpleType>
+
+ <xs:simpleType name="DistinguishedFolderIdNameType">
+ <xs:annotation>
+ <xs:documentation>URIs for the distinguished folders accessible from a mailbox</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="calendar" />
+ <xs:enumeration value="contacts" />
+ <xs:enumeration value="deleteditems" />
+ <xs:enumeration value="drafts" />
+ <xs:enumeration value="inbox" />
+ <xs:enumeration value="journal" />
+ <xs:enumeration value="notes" />
+ <xs:enumeration value="outbox" />
+ <xs:enumeration value="sentitems" />
+ <xs:enumeration value="tasks" />
+ <xs:enumeration value="msgfolderroot" />
+ <xs:enumeration value="publicfoldersroot" />
+ <xs:enumeration value="root" />
+ <xs:enumeration value="junkemail" />
+ <xs:enumeration value="searchfolders" />
+ <xs:enumeration value="voicemail" />
+ <xs:enumeration value="recoverableitemsroot" />
+ <xs:enumeration value="recoverableitemsdeletions" />
+ <xs:enumeration value="recoverableitemsversions" />
+ <xs:enumeration value="recoverableitemspurges" />
+ <xs:enumeration value="recoverableitemsdiscoveryholds" />
+ <xs:enumeration value="archiveroot" />
+ <xs:enumeration value="archivemsgfolderroot" />
+ <xs:enumeration value="archivedeleteditems" />
+ <xs:enumeration value="archiveinbox" />
+ <xs:enumeration value="archiverecoverableitemsroot" />
+ <xs:enumeration value="archiverecoverableitemsdeletions" />
+ <xs:enumeration value="archiverecoverableitemsversions" />
+ <xs:enumeration value="archiverecoverableitemspurges" />
+ <xs:enumeration value="archiverecoverableitemsdiscoveryholds" />
+ <xs:enumeration value="syncissues" />
+ <xs:enumeration value="conflicts" />
+ <xs:enumeration value="localfailures" />
+ <xs:enumeration value="serverfailures" />
+ <xs:enumeration value="recipientcache" />
+ <xs:enumeration value="quickcontacts" />
+ <xs:enumeration value="conversationhistory" />
+ <xs:enumeration value="adminauditlogs" />
+ <xs:enumeration value="todosearch" />
+ <xs:enumeration value="mycontacts" />
+ <xs:enumeration value="directory" />
+ <xs:enumeration value="imcontactlist" />
+ <xs:enumeration value="peopleconnect" />
+ <xs:enumeration value="favorites" />
+ <xs:enumeration value="mecontact" />
+ <xs:enumeration value="personmetadata" />
+ <xs:enumeration value="teamspaceactivity" />
+ <xs:enumeration value="teamspacemessaging" />
+ <xs:enumeration value="teamspaceworkitems" />
+ <xs:enumeration value="scheduled" />
+ <xs:enumeration value="orionnotes" />
+ <xs:enumeration value="tagitems" />
+ <xs:enumeration value="alltaggeditems" />
+ <xs:enumeration value="externalcontacts" />
+ <xs:enumeration value="teamchat" />
+ <xs:enumeration value="yammerroot" />
+ <xs:enumeration value="yammerinbound" />
+ <xs:enumeration value="yammeroutbound" />
+ <xs:enumeration value="yammerfeeds" />
+ <xs:enumeration value="onedriveroot" />
+ <xs:enumeration value="onedriverecylebin" />
+ <xs:enumeration value="onedrivesystem" />
+ <xs:enumeration value="onedrivevolume" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="DistinguishedFolderIdType">
+ <xs:annotation>
+ <xs:documentation>Identifier for a distinguished folder</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BaseFolderIdType">
+ <xs:sequence>
+ <xs:element name="Mailbox" type="t:EmailAddressType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="Id" type="t:DistinguishedFolderIdNameType" use="required" />
+ <xs:attribute name="ChangeKey" type="xs:string" use="optional" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="FolderIdType">
+ <xs:annotation>
+ <xs:documentation>Identifier for a fully resolved folder</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BaseFolderIdType">
+ <xs:attribute name="Id" type="xs:string" use="required" />
+ <xs:attribute name="ChangeKey" type="xs:string" use="optional" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AddressListIdType">
+ <xs:annotation>
+ <xs:documentation>Identifier for a address list</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BaseFolderIdType">
+ <xs:attribute name="Id" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfDistinguishedFolderIdType">
+ <xs:choice maxOccurs="unbounded" minOccurs="0">
+ <xs:element name="DistinguishedFolderId" type="t:DistinguishedFolderIdType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfBaseFolderIdsType">
+ <xs:choice maxOccurs="unbounded" minOccurs="1">
+ <xs:element name="FolderId" type="t:FolderIdType"/>
+ <xs:element name="DistinguishedFolderId" type="t:DistinguishedFolderIdType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="TargetFolderIdType">
+ <xs:choice>
+ <xs:element name="FolderId" type="t:FolderIdType"/>
+ <xs:element name="DistinguishedFolderId" type="t:DistinguishedFolderIdType"/>
+ <xs:element name="AddressListId" type="t:AddressListIdType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- UploadItems types -->
+ <xs:complexType name="NonEmptyArrayOfUploadItemsType">
+ <xs:sequence>
+ <xs:element name="Item" type="t:UploadItemType" maxOccurs="unbounded" minOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- UploadItemType-->
+ <xs:complexType name="UploadItemType">
+ <xs:sequence>
+ <xs:element name="ParentFolderId" type="t:FolderIdType" maxOccurs ="1" minOccurs ="1"/>
+ <xs:element name="ItemId" type="t:ItemIdType" maxOccurs ="1" minOccurs="0"/>
+ <xs:element name="Data" type="xs:base64Binary" maxOccurs ="1" minOccurs ="1"/>
+ </xs:sequence>
+ <xs:attribute name="CreateAction" type="t:CreateActionType" use="required"/>
+ <xs:attribute name="IsAssociated" type="xs:boolean" use="optional"/>
+ </xs:complexType>
+
+ <!-- CreateActionType -->
+ <xs:simpleType name="CreateActionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="CreateNew"/>
+ <xs:enumeration value="Update"/>
+ <xs:enumeration value="UpdateOrCreate"/>
+ </xs:restriction >
+ </xs:simpleType>
+
+ <!-- CompleteActionType -->
+ <xs:simpleType name="CompleteActionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Commit"/>
+ <xs:enumeration value="Abandon"/>
+ </xs:restriction >
+ </xs:simpleType>
+
+ <!-- Find Folder/Item/Search supporting types -->
+ <!-- When returning offset information for FindFolder/FindItem, we need to indicate where we
+ are in the result set. For the different paging mechanisms we need to indicate this in
+ different ways. The only common paging types between FindFolder and FindItem are indexed and
+ fractional.
+ -->
+ <xs:attributeGroup name="FindResponsePagingAttributes">
+ <xs:attribute name="IndexedPagingOffset" type="xs:int" use="optional"/>
+ <xs:attribute name="NumeratorOffset" type="xs:int" use="optional"/>
+ <xs:attribute name="AbsoluteDenominator" type="xs:int" use="optional"/>
+ <xs:attribute name="IncludesLastItemInRange" type="xs:boolean" use="optional"/>
+ <xs:attribute name="TotalItemsInView" type="xs:int" use="optional"/>
+ </xs:attributeGroup>
+
+ <xs:simpleType name="ViewFilterType">
+ <xs:annotation>
+ <xs:documentation>Types of view filters for finding items/conversations</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="All" />
+ <xs:enumeration value="Flagged" />
+ <xs:enumeration value="HasAttachment" />
+ <xs:enumeration value="ToOrCcMe" />
+ <xs:enumeration value="Unread" />
+ <xs:enumeration value="TaskActive" />
+ <xs:enumeration value="TaskOverdue" />
+ <xs:enumeration value="TaskCompleted" />
+ <xs:enumeration value="NoClutter" />
+ <xs:enumeration value="Clutter" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- FindFolder response element for holding the results from a single parent -->
+ <xs:complexType name="FindFolderParentType">
+ <xs:sequence>
+ <xs:element name="Folders" type="t:ArrayOfFoldersType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attributeGroup ref="t:FindResponsePagingAttributes"/>
+ </xs:complexType>
+
+ <!-- Basic information in a folder definition -->
+ <xs:complexType name="BaseFolderType" abstract ="true">
+ <xs:sequence>
+ <xs:element name="FolderId" type="t:FolderIdType" minOccurs="0"/>
+ <xs:element name="ParentFolderId" type="t:FolderIdType" minOccurs="0"/>
+ <xs:element name="FolderClass" type="xs:string" minOccurs="0"/>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0"/>
+ <xs:element name="TotalCount" type="xs:int" minOccurs="0"/>
+ <xs:element name="ChildFolderCount" type="xs:int" minOccurs="0"/>
+ <xs:element name="ExtendedProperty" type="t:ExtendedPropertyType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="ManagedFolderInformation" type="t:ManagedFolderInformationType" minOccurs="0"/>
+ <xs:element name="EffectiveRights" type="t:EffectiveRightsType" minOccurs="0"/>
+ <xs:element name="DistinguishedFolderId" type="t:DistinguishedFolderIdNameType" minOccurs="0"/>
+ <xs:element name="PolicyTag" type="t:RetentionTagType" minOccurs="0" />
+ <xs:element name="ArchiveTag" type="t:RetentionTagType" minOccurs="0" />
+ <xs:element name="ReplicaList" type="t:ArrayOfStringsType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- ManagedFolderInformation property type -->
+ <xs:complexType name="ManagedFolderInformationType">
+ <xs:annotation>
+ <xs:documentation>Compound property for Managed Folder related information for Managed Folders.</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="CanDelete" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="CanRenameOrMove" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="MustDisplayComment" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="HasQuota" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="IsManagedFoldersRoot" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="ManagedFolderId" type="xs:string" minOccurs="0"/>
+ <xs:element name="Comment" type="xs:string" minOccurs="0"/>
+ <xs:element name="StorageQuota" type="xs:int" minOccurs="0"/>
+ <xs:element name="FolderSize" type="xs:int" minOccurs="0"/>
+ <xs:element name="HomePage" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FolderType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseFolderType">
+ <xs:sequence>
+ <xs:element name="PermissionSet" type="t:PermissionSetType" minOccurs="0"/>
+ <xs:element name="UnreadCount" type="xs:int" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Calendar Folder Type-->
+ <xs:complexType name="CalendarFolderType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseFolderType">
+ <xs:sequence>
+ <xs:element name="SharingEffectiveRights" type="t:CalendarPermissionReadAccessType" minOccurs="0"/>
+ <xs:element name="PermissionSet" type="t:CalendarPermissionSetType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Reminder Action Type -->
+ <xs:simpleType name="ReminderActionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Dismiss"/>
+ <xs:enumeration value="Snooze"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ReminderItemActionType">
+ <xs:sequence>
+ <xs:element name="ActionType" type="t:ReminderActionType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs ="1" maxOccurs ="1" />
+ <xs:element name="NewReminderTime" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfReminderItemActionType">
+ <xs:sequence>
+ <xs:element name="ReminderItemAction" type="t:ReminderItemActionType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Contacts Folder Type-->
+ <xs:complexType name="ContactsFolderType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseFolderType">
+ <xs:sequence>
+ <xs:element name="SharingEffectiveRights" type="t:PermissionReadAccessType" minOccurs="0"/>
+ <xs:element name="PermissionSet" type="t:PermissionSetType" minOccurs="0"/>
+ <xs:element name="SourceId" type="xs:string" minOccurs="0"/>
+ <xs:element name="AccountName" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Search Folder Type-->
+ <xs:complexType name="SearchFolderType">
+ <xs:complexContent>
+ <xs:extension base="t:FolderType">
+ <xs:sequence>
+ <xs:element name="SearchParameters" type="t:SearchParametersType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Tasks Folder Type-->
+ <xs:complexType name="TasksFolderType">
+ <xs:complexContent>
+ <xs:extension base="t:FolderType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfFoldersType">
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="Folder" type="t:FolderType"/>
+ <xs:element name="CalendarFolder" type="t:CalendarFolderType"/>
+ <xs:element name="ContactsFolder" type="t:ContactsFolderType"/>
+ <xs:element name="SearchFolder" type="t:SearchFolderType"/>
+ <xs:element name="TasksFolder" type="t:TasksFolderType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfFoldersType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Folder" type="t:FolderType"/>
+ <xs:element name="CalendarFolder" type="t:CalendarFolderType"/>
+ <xs:element name="ContactsFolder" type="t:ContactsFolderType"/>
+ <xs:element name="SearchFolder" type="t:SearchFolderType"/>
+ <xs:element name="TasksFolder" type="t:TasksFolderType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- Item Service types. -->
+ <xs:complexType name="BaseItemIdType" abstract="true">
+ <xs:annotation>
+ <xs:documentation>Abstract base type for item identifiers. Should never be used in web service calls</xs:documentation>
+ </xs:annotation>
+ </xs:complexType>
+ <xs:element name="BaseItemId" type="t:BaseItemIdType" />
+
+ <xs:simpleType name="DerivedItemIdType">
+ <xs:restriction base="xs:string" />
+ </xs:simpleType>
+
+ <xs:complexType name="ItemIdType">
+ <xs:annotation>
+ <xs:documentation>Identifier for a fully resolved item</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BaseItemIdType">
+ <xs:attribute name="Id" type="xs:string" use="required" />
+ <xs:attribute name="ChangeKey" type="xs:string" use="optional" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfBaseItemIdsType">
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="ItemId" type="t:ItemIdType"/>
+ <xs:element name="OccurrenceItemId" type="t:OccurrenceItemIdType"/>
+ <xs:element name="RecurringMasterItemId" type="t:RecurringMasterItemIdType"/>
+ <xs:element name="RecurringMasterItemIdRanges" type="t:RecurringMasterItemIdRangesType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfBaseItemIdsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="ItemId" type="t:ItemIdType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfItemIdsType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" maxOccurs="unbounded" minOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfItemIdsType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" maxOccurs="unbounded" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Item classes -->
+ <xs:simpleType name="ItemClassType">
+ <xs:restriction base="xs:string" />
+ </xs:simpleType>
+
+ <!--Reply objects-->
+ <xs:complexType name="ResponseObjectCoreType" abstract="true">
+ <xs:annotation>
+ <xs:documentation>
+ Internal abstract base type for reply objects.
+ Should not appear in client code
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:MessageType">
+ <xs:sequence>
+ <xs:element name="ReferenceItemId" type="t:ItemIdType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ResponseObjectType" abstract="true">
+ <xs:annotation>
+ <xs:documentation>Abstract base type for reply objects</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:ResponseObjectCoreType">
+ <xs:attribute name="ObjectName" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>
+ The name of this reply object class as an English string. The client
+ application is required to translate it if it's running in a different locale
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!--The wrapper around all reply object types-->
+ <xs:complexType name="NonEmptyArrayOfResponseObjectsType">
+ <xs:choice maxOccurs="unbounded" minOccurs="0">
+ <xs:element name="AcceptItem" type="t:AcceptItemType"/>
+ <xs:element name="TentativelyAcceptItem" type="t:TentativelyAcceptItemType"/>
+ <xs:element name="DeclineItem" type="t:DeclineItemType"/>
+ <xs:element name="ReplyToItem" type="t:ReplyToItemType" />
+ <xs:element name="ForwardItem" type="t:ForwardItemType" />
+ <xs:element name="ReplyAllToItem" type="t:ReplyAllToItemType" />
+ <xs:element name="CancelCalendarItem" type="t:CancelCalendarItemType" />
+ <xs:element name="RemoveItem" type="t:RemoveItemType" />
+ <xs:element name="SuppressReadReceipt" type="t:SuppressReadReceiptType" />
+ <xs:element name="PostReplyItem" type="t:PostReplyItemType" />
+ <xs:element name="AcceptSharingInvitation" type="t:AcceptSharingInvitationType" />
+ <xs:element name="AddItemToMyCalendar" type="t:AddItemToMyCalendarType" />
+ <xs:element name="ProposeNewTime" type="t:ProposeNewTimeType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- Updating an folder. Represents a set of changes to a single folder -->
+ <xs:complexType name="FolderChangeType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="FolderId" type="t:FolderIdType" />
+ <xs:element name="DistinguishedFolderId" type="t:DistinguishedFolderIdType"/>
+ </xs:choice>
+ <xs:element name="Updates" type="t:NonEmptyArrayOfFolderChangeDescriptionsType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfFolderChangesType">
+ <xs:sequence>
+ <xs:element name="FolderChange" type="t:FolderChangeType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Generic response to deleting a folder -->
+ <!-- Some well-known reply objects -->
+ <xs:complexType name="WellKnownResponseObjectType">
+ <xs:complexContent>
+ <xs:restriction base="t:ResponseObjectType">
+ <xs:sequence>
+ <xs:element name="ItemClass" type="t:ItemClassType" minOccurs="0" />
+ <xs:element name="Sensitivity" type="t:SensitivityChoicesType" minOccurs="0" />
+ <xs:element name="Body" type="t:BodyType" minOccurs="0" />
+ <xs:element name="Attachments" type="t:NonEmptyArrayOfAttachmentsType" minOccurs="0" />
+ <xs:element
+ name="InternetMessageHeaders"
+ type="t:NonEmptyArrayOfInternetHeadersType"
+ minOccurs="0" />
+ <xs:element name="Sender" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="ToRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="CcRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="BccRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="IsReadReceiptRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsDeliveryReceiptRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="From" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="ReferenceItemId" type="t:ItemIdType" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="ObjectName" type="xs:string" use="prohibited" />
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- Smart reponses: ReplyToItem, ReplyAllToItem, ForwardItem-->
+ <xs:complexType name="SmartResponseBaseType">
+ <xs:complexContent>
+ <xs:restriction base="t:ResponseObjectType">
+ <xs:sequence>
+ <xs:element name="Subject" type="xs:string" minOccurs="0" />
+ <xs:element name="Body" type="t:BodyType" minOccurs="0" />
+ <xs:element name="ToRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="CcRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="BccRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="IsReadReceiptRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsDeliveryReceiptRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="From" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="ReferenceItemId" type="t:ItemIdType" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="ObjectName" type="xs:string" use="prohibited" />
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="SmartResponseType">
+ <xs:complexContent>
+ <xs:extension base="t:SmartResponseBaseType">
+ <xs:sequence>
+ <xs:element name="NewBodyContent" type="t:BodyType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <!-- Distinguish the various kinds of responses which differ only in name by making them -->
+ <!-- have types which all extend the same base types trivially -->
+ <xs:complexType name="ReplyToItemType">
+ <xs:complexContent>
+ <xs:extension base="t:SmartResponseType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="ReplyAllToItemType">
+ <xs:complexContent>
+ <xs:extension base="t:SmartResponseType">
+ <xs:sequence>
+ <xs:element name="IsSpecificMessageReply" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="ForwardItemType">
+ <xs:complexContent>
+ <xs:extension base="t:SmartResponseType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="CancelCalendarItemType">
+ <xs:complexContent>
+ <xs:extension base="t:SmartResponseType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Reference Item response object -->
+
+ <xs:complexType name="ReferenceItemResponseType">
+ <xs:complexContent>
+ <xs:restriction base="t:ResponseObjectType">
+ <xs:sequence>
+ <xs:element name="ReferenceItemId" type="t:ItemIdType" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="ObjectName" type="xs:string" use="prohibited" />
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SuppressReadReceiptType">
+ <xs:complexContent>
+ <xs:extension base="t:ReferenceItemResponseType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- FindItem response element for holding the results from a single parent -->
+ <xs:complexType name="FindItemParentType">
+ <xs:choice>
+ <xs:element name="Items" type="t:ArrayOfRealItemsType"/>
+ <xs:element name="Groups" type="t:ArrayOfGroupedItemsType"/>
+ </xs:choice>
+ <xs:attributeGroup ref="t:FindResponsePagingAttributes"/>
+ </xs:complexType>
+
+ <!-- Core contents of an item. -->
+ <xs:complexType name="ItemType">
+ <xs:sequence>
+ <xs:element name="MimeContent" type="t:MimeContentType" minOccurs="0" />
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="0" />
+ <xs:element name="ParentFolderId" type="t:FolderIdType" minOccurs="0"/>
+ <xs:element name="ItemClass" type="t:ItemClassType" minOccurs="0" />
+ <xs:element name="Subject" type="xs:string" minOccurs="0" />
+ <xs:element name="Sensitivity" type="t:SensitivityChoicesType" minOccurs="0" />
+ <xs:element name="Body" type="t:BodyType" minOccurs="0" />
+ <xs:element name="Attachments" type="t:NonEmptyArrayOfAttachmentsType" minOccurs="0" />
+ <xs:element name="DateTimeReceived" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="Size" type="xs:int" minOccurs="0" />
+ <xs:element name="Categories" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="Importance" type="t:ImportanceChoicesType" minOccurs="0" />
+ <xs:element name="InReplyTo" type="xs:string" minOccurs="0" />
+ <xs:element name="IsSubmitted" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsDraft" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsFromMe" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsResend" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsUnmodified" type="xs:boolean" minOccurs="0" />
+ <xs:element name="InternetMessageHeaders" type="t:NonEmptyArrayOfInternetHeadersType" minOccurs="0" />
+ <xs:element name="DateTimeSent" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="DateTimeCreated" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="ResponseObjects" type="t:NonEmptyArrayOfResponseObjectsType" minOccurs="0" />
+ <xs:element name="ReminderDueBy" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="ReminderIsSet" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ReminderNextTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="ReminderMinutesBeforeStart" type="t:ReminderMinutesBeforeStartType" minOccurs="0" />
+ <xs:element name="DisplayCc" type="xs:string" minOccurs="0" />
+ <xs:element name="DisplayTo" type="xs:string" minOccurs="0" />
+ <xs:element name="DisplayBcc" type="xs:string" minOccurs="0" />
+ <xs:element name="HasAttachments" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="ExtendedProperty" type="t:ExtendedPropertyType" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element name="Culture" type="xs:language" minOccurs="0"/>
+ <xs:element name="EffectiveRights" type="t:EffectiveRightsType" minOccurs="0" />
+ <xs:element name="LastModifiedName" type="xs:string" minOccurs="0" />
+ <xs:element name="LastModifiedTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="IsAssociated" type="xs:boolean" minOccurs="0" />
+ <xs:element name="WebClientReadFormQueryString" type="xs:string" minOccurs="0" />
+ <xs:element name="WebClientEditFormQueryString" type="xs:string" minOccurs="0" />
+ <xs:element name="ConversationId" type="t:ItemIdType" minOccurs="0" />
+ <xs:element name="UniqueBody" type="t:BodyType" minOccurs="0" />
+ <xs:element name="Flag" type="t:FlagType" minOccurs="0" />
+ <xs:element name="StoreEntryId" type="xs:base64Binary" minOccurs="0" />
+ <xs:element name="InstanceKey" type="xs:base64Binary" minOccurs="0" />
+ <xs:element name="NormalizedBody" type="t:BodyType" minOccurs="0"/>
+ <xs:element name="EntityExtractionResult" type="t:EntityExtractionResultType" minOccurs="0" />
+ <xs:element name="PolicyTag" type="t:RetentionTagType" minOccurs="0" />
+ <xs:element name="ArchiveTag" type="t:RetentionTagType" minOccurs="0" />
+ <xs:element name="RetentionDate" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="Preview" type="xs:string" minOccurs="0" />
+ <xs:element name="RightsManagementLicenseData" type="t:RightsManagementLicenseDataType" minOccurs="0" />
+ <xs:element name="PredictedActionReasons" type="t:NonEmptyArrayOfPredictedActionReasonType" minOccurs="0" />
+ <xs:element name="IsClutter" type="xs:boolean" minOccurs="0" />
+ <xs:element name="BlockStatus" type="xs:boolean" minOccurs="0" />
+ <xs:element name="HasBlockedImages" type="xs:boolean" minOccurs="0" />
+ <xs:element name="TextBody" type="t:BodyType" minOccurs="0"/>
+ <xs:element name="IconIndex" type="t:IconIndexType" minOccurs="0"/>
+ <xs:element name="SearchKey" type="xs:base64Binary" minOccurs="0" />
+ <xs:element name="SortKey" type="xs:long" minOccurs="0" />
+ <xs:element name="Hashtags" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="Mentions" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="MentionedMe" type="xs:boolean" minOccurs="0" />
+ <xs:element name="MentionsPreview" type="t:MentionsPreviewType" minOccurs="0" />
+ <xs:element name="MentionsEx" type="t:NonEmptyArrayOfMentionActionsType" minOccurs="0" />
+ <xs:element name="AppliedHashtags" type="t:NonEmptyArrayOfAppliedHashtagType" minOccurs="0" />
+ <xs:element name="AppliedHashtagsPreview" type="t:AppliedHashtagsPreviewType" minOccurs="0" />
+ <xs:element name="Likes" type="t:NonEmptyArrayOfLikeType" minOccurs="0" />
+ <xs:element name="LikesPreview" type="t:LikesPreviewType" minOccurs="0" />
+ <xs:element name="PendingSocialActivityTagIds" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="AtAllMention" type="xs:boolean" minOccurs="0" />
+ <xs:element name="CanDelete" type="xs:boolean" minOccurs="0" />
+ <xs:element name="InferenceClassification" type="t:InferenceClassificationType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfItemClassType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="ItemClass" type="t:ItemClassType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="FlagType">
+ <xs:sequence>
+ <xs:element name="FlagStatus" type="t:FlagStatusType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="StartDate" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="DueDate" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="CompleteDate" type="xs:dateTime" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="FlagStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NotFlagged" />
+ <xs:enumeration value="Flagged" />
+ <xs:enumeration value="Complete" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="PredictedActionReasonType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="ConversationStarterIsYou" />
+ <xs:enumeration value="OnlyRecipient" />
+ <xs:enumeration value="ConversationContributions" />
+ <xs:enumeration value="MarkedImportantBySender" />
+ <xs:enumeration value="SenderIsManager" />
+ <xs:enumeration value="SenderIsInManagementChain" />
+ <xs:enumeration value="SenderIsDirectReport" />
+ <xs:enumeration value="ActionBasedOnSender" />
+ <xs:enumeration value="NameOnToLine" />
+ <xs:enumeration value="NameOnCcLine" />
+ <xs:enumeration value="ManagerPosition" />
+ <xs:enumeration value="ReplyToAMessageFromMe" />
+ <xs:enumeration value="PreviouslyFlagged" />
+ <xs:enumeration value="ActionBasedOnRecipients" />
+ <xs:enumeration value="ActionBasedOnSubjectWords" />
+ <xs:enumeration value="ActionBasedOnBasedOnBodyWords" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Begin Entity Extraction -->
+ <xs:complexType name="EntityType">
+ <xs:sequence>
+ <xs:element name="Position" type="t:EmailPositionType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfAddressesType">
+ <xs:sequence>
+ <xs:element name="Address" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfAddressEntitiesType">
+ <xs:sequence>
+ <xs:element name="AddressEntity" type="t:AddressEntityType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AddressEntityType">
+ <xs:complexContent>
+ <xs:extension base="t:EntityType">
+ <xs:sequence>
+ <xs:element name="Address" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfEmailAddressEntitiesType">
+ <xs:sequence>
+ <xs:element name="EmailAddressEntity" type="t:EmailAddressEntityType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EmailAddressEntityType">
+ <xs:complexContent>
+ <xs:extension base="t:EntityType">
+ <xs:sequence>
+ <xs:element name="EmailAddress" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfUrlEntitiesType">
+ <xs:sequence>
+ <xs:element name="UrlEntity" type="t:UrlEntityType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="UrlEntityType">
+ <xs:complexContent>
+ <xs:extension base="t:EntityType">
+ <xs:sequence>
+ <xs:element name="Url" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfMeetingSuggestionsType">
+ <xs:sequence>
+ <xs:element name="MeetingSuggestion" type="t:MeetingSuggestionType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingSuggestionType">
+ <xs:complexContent>
+ <xs:extension base="t:EntityType">
+ <xs:sequence>
+ <xs:element name="Attendees" type="t:ArrayOfEmailUsersType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" />
+ <xs:element name="Subject" type="xs:string" minOccurs="0" />
+ <xs:element name="MeetingString" type="xs:string" minOccurs="0" />
+ <xs:element name="StartTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="EndTime" type="xs:dateTime" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfTaskSuggestionsType">
+ <xs:sequence>
+ <xs:element name="TaskSuggestion" type="t:TaskSuggestionType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfContactsType">
+ <xs:sequence>
+ <xs:element name="Contact" type="t:ContactType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ContactType">
+ <xs:complexContent>
+ <xs:extension base="t:EntityType">
+ <xs:sequence>
+ <xs:element name="PersonName" type="xs:string" minOccurs="0" />
+ <xs:element name="BusinessName" type="xs:string" minOccurs="0" />
+ <xs:element name="PhoneNumbers" type="t:ArrayOfPhonesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Urls" type="t:ArrayOfUrlsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EmailAddresses" type="t:ArrayOfExtractedEmailAddresses" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Addresses" type="t:ArrayOfAddressesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContactString" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfUrlsType">
+ <xs:sequence>
+ <xs:element name="Url" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPhonesType">
+ <xs:sequence>
+ <xs:element name="Phone" type="t:PhoneType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PhoneType">
+ <xs:sequence>
+ <xs:element name="OriginalPhoneString" type="xs:string" minOccurs="0" />
+ <xs:element name="PhoneString" type="xs:string" minOccurs="0" />
+ <xs:element name="Type" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPhoneEntitiesType">
+ <xs:sequence>
+ <xs:element name="Phone" type="t:PhoneEntityType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PhoneEntityType">
+ <xs:complexContent>
+ <xs:extension base="t:EntityType">
+ <xs:sequence>
+ <xs:element name="OriginalPhoneString" type="xs:string" minOccurs="0" />
+ <xs:element name="PhoneString" type="xs:string" minOccurs="0" />
+ <xs:element name="Type" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="EmailPositionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="LatestReply" />
+ <xs:enumeration value="Other" />
+ <xs:enumeration value="Subject" />
+ <xs:enumeration value="Signature" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfEmailUsersType">
+ <xs:sequence>
+ <xs:element name="EmailUser" type="t:EmailUserType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EmailUserType">
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="0" />
+ <xs:element name="UserId" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="TaskSuggestionType">
+ <xs:complexContent>
+ <xs:extension base="t:EntityType">
+ <xs:sequence>
+ <xs:element name="TaskString" type="xs:string" minOccurs="0" />
+ <xs:element name="Assignees" type="t:ArrayOfEmailUsersType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfExtractedEmailAddresses">
+ <xs:sequence>
+ <xs:element name="EmailAddress" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ParcelDeliveryEntityType">
+ <xs:sequence>
+ <xs:element name="Carrier" type="xs:string" minOccurs="0" />
+ <xs:element name="TrackingNumber" type="xs:string" minOccurs="0" />
+ <xs:element name="TrackingUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="ExpectedArrivalFrom" type="xs:string" minOccurs="0" />
+ <xs:element name="ExpectedArrivalUntil" type="xs:string" minOccurs="0" />
+ <xs:element name="Product" type="xs:string" minOccurs="0" />
+ <xs:element name="ProductUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="ProductImage" type="xs:string" minOccurs="0" />
+ <xs:element name="ProductSku" type="xs:string" minOccurs="0" />
+ <xs:element name="ProductDescription" type="xs:string" minOccurs="0" />
+ <xs:element name="ProductBrand" type="xs:string" minOccurs="0" />
+ <xs:element name="ProductColor" type="xs:string" minOccurs="0" />
+ <xs:element name="OrderNumber" type="xs:string" minOccurs="0" />
+ <xs:element name="Seller" type="xs:string" minOccurs="0" />
+ <xs:element name="OrderStatus" type="xs:string" minOccurs="0" />
+ <xs:element name="AddressName" type="xs:string" minOccurs="0" />
+ <xs:element name="StreetAddress" type="xs:string" minOccurs="0" />
+ <xs:element name="AddressLocality" type="xs:string" minOccurs="0" />
+ <xs:element name="AddressRegion" type="xs:string" minOccurs="0" />
+ <xs:element name="AddressCountry" type="xs:string" minOccurs="0" />
+ <xs:element name="PostalCode" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="InferenceClassificationType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Focused" />
+ <xs:enumeration value="Other" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="InferenceClassificationOverrideType">
+ <xs:sequence>
+ <xs:element name="Id" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SenderSmtpAddress" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SenderDisplayName" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="AlwaysClassifyAs" type="t:InferenceClassificationType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ArrayOfInferenceClassificationOverridesType">
+ <xs:sequence>
+ <xs:element name="Override" minOccurs="0" maxOccurs="unbounded" type="t:InferenceClassificationOverrideType"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfParcelDeliveryEntitiesType">
+ <xs:sequence>
+ <xs:element name="ParcelDelivery" type="t:ParcelDeliveryEntityType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FlightEntityType">
+ <xs:sequence>
+ <xs:element name="FlightNumber" type="xs:string" minOccurs="0" />
+ <xs:element name="AirlineIataCode" type="xs:string" minOccurs="0" />
+ <xs:element name="DepartureTime" type="xs:string" minOccurs="0" />
+ <xs:element name="WindowsTimeZoneName" type="xs:string" minOccurs="0" />
+ <xs:element name="DepartureAirportIataCode" type="xs:string" minOccurs="0" />
+ <xs:element name="ArrivalAirportIataCode" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfFlightsType">
+ <xs:sequence>
+ <xs:element name="Flight" type="t:FlightEntityType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FlightReservationEntityType">
+ <xs:sequence>
+ <xs:element name="ReservationId" type="xs:string" minOccurs="0" />
+ <xs:element name="ReservationStatus" type="xs:string" minOccurs="0" />
+ <xs:element name="UnderName" type="xs:string" minOccurs="0" />
+ <xs:element name="BrokerName" type="xs:string" minOccurs="0" />
+ <xs:element name="BrokerPhone" type="xs:string" minOccurs="0" />
+ <xs:element name="Flights" type="t:ArrayOfFlightsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfFlightReservationsType">
+ <xs:sequence>
+ <xs:element name="FlightReservation" type="t:FlightReservationEntityType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SenderAddInEntityType">
+ <xs:sequence>
+ <xs:element name="ExtensionId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSenderAddInsType">
+ <xs:sequence>
+ <xs:element name="Microsoft.OutlookServices.SenderApp" type="t:SenderAddInEntityType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EntityExtractionResultType">
+ <xs:sequence>
+ <xs:element name="Addresses" type="t:ArrayOfAddressEntitiesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MeetingSuggestions" type="t:ArrayOfMeetingSuggestionsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="TaskSuggestions" type="t:ArrayOfTaskSuggestionsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EmailAddresses" type="t:ArrayOfEmailAddressEntitiesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Contacts" type="t:ArrayOfContactsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Urls" type="t:ArrayOfUrlEntitiesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PhoneNumbers" type="t:ArrayOfPhoneEntitiesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ParcelDeliveries" type="t:ArrayOfParcelDeliveryEntitiesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FlightReservations" type="t:ArrayOfFlightReservationsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SenderAddIns" type="t:ArrayOfSenderAddInsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- End Entity Extraction -->
+
+ <!-- Begin Rights Management License Data -->
+ <xs:complexType name="RightsManagementLicenseDataType">
+ <xs:sequence>
+ <xs:element name="RightsManagedMessageDecryptionStatus" type="xs:int" minOccurs="0" />
+ <xs:element name="RmsTemplateId" type="xs:string" minOccurs="0" />
+ <xs:element name="TemplateName" type="xs:string" minOccurs="0" />
+ <xs:element name="TemplateDescription" type="xs:string" minOccurs="0" />
+ <xs:element name="EditAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ReplyAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ReplyAllAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ForwardAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ModifyRecipientsAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ExtractAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="PrintAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ExportAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ProgrammaticAccessAllowed" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsOwner" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ContentOwner" type="xs:string" minOccurs="0" />
+ <xs:element name="ContentExpiryDate" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- End Rights Management License Data -->
+
+ <xs:simpleType name="ConversationActionTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AlwaysCategorize" />
+ <xs:enumeration value="AlwaysDelete" />
+ <xs:enumeration value="AlwaysMove" />
+ <xs:enumeration value="Delete" />
+ <xs:enumeration value="Move" />
+ <xs:enumeration value="Copy" />
+ <xs:enumeration value="SetReadState" />
+ <xs:enumeration value="SetRetentionPolicy" />
+ <xs:enumeration value="Flag" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ConversationActionType">
+ <xs:sequence>
+ <xs:element name="Action" type="t:ConversationActionTypeType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ConversationId" type="t:ItemIdType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ContextFolderId" type="t:TargetFolderIdType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ConversationLastSyncTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ProcessRightAway" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DestinationFolderId" type="t:TargetFolderIdType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Categories" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EnableAlwaysDelete" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsRead" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DeleteType" type="t:DisposalType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="RetentionPolicyType" type="t:RetentionType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="RetentionPolicyTagId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Flag" type="t:FlagType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SuppressReadReceipts" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfApplyConversationActionType">
+ <xs:sequence>
+ <xs:element name="ConversationAction" type="t:ConversationActionType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <xs:complexType name="ConversationType">
+ <xs:sequence>
+ <xs:element name="ConversationId" type="t:ItemIdType" minOccurs="0" />
+ <xs:element name="ConversationTopic" type="xs:string" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationMVTo-->
+ <xs:element name="UniqueRecipients" type="t:ArrayOfStringsType" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalMVTo-->
+ <xs:element name="GlobalUniqueRecipients" type="t:ArrayOfStringsType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationMVUnreadFrom-->
+ <xs:element name="UniqueUnreadSenders" type="t:ArrayOfStringsType" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalMVUnreadFrom-->
+ <xs:element name="GlobalUniqueUnreadSenders" type="t:ArrayOfStringsType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationMVFrom-->
+ <xs:element name="UniqueSenders" type="t:ArrayOfStringsType" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationMVFrom-->
+ <xs:element name="GlobalUniqueSenders" type="t:ArrayOfStringsType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationLastDeliveryTime-->
+ <xs:element name="LastDeliveryTime" type="xs:dateTime" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalLastDeliveryTime-->
+ <xs:element name="GlobalLastDeliveryTime" type="xs:dateTime" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationCategories-->
+ <xs:element name="Categories" type="t:ArrayOfStringsType" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalCategories-->
+ <xs:element name="GlobalCategories" type="t:ArrayOfStringsType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationFlagStatus-->
+ <xs:element name="FlagStatus" type="t:FlagStatusType" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalFlagStatus-->
+ <xs:element name="GlobalFlagStatus" type="t:FlagStatusType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationHasAttach-->
+ <xs:element name="HasAttachments" type="xs:boolean" minOccurs="0"/>
+ <!-- Maps to ConversationItemSchema.ConversationGlobalHasAttach-->
+ <xs:element name="GlobalHasAttachments" type="xs:boolean" minOccurs="0"/>
+
+ <!-- Maps to ConversationItemSchema.ConversationMessageCount-->
+ <xs:element name="MessageCount" type="xs:int" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalMessageCount-->
+ <xs:element name="GlobalMessageCount" type="xs:int" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationUnreadMessageCount-->
+ <xs:element name="UnreadCount" type="xs:int" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalUnreadMessageCount-->
+ <xs:element name="GlobalUnreadCount" type="xs:int" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationMessageSize-->
+ <xs:element name="Size" type="xs:int" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalMessageSize-->
+ <xs:element name="GlobalSize" type="xs:int" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationMessageClasses-->
+ <xs:element name="ItemClasses" type="t:ArrayOfItemClassType" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalMessageClasses-->
+ <xs:element name="GlobalItemClasses" type="t:ArrayOfItemClassType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationImportance-->
+ <xs:element name="Importance" type="t:ImportanceChoicesType" minOccurs="0" />
+ <!-- Maps to ConversationItemSchema.ConversationGlobalImportance-->
+ <xs:element name="GlobalImportance" type="t:ImportanceChoicesType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationItemIds-->
+ <xs:element name="ItemIds" type="t:NonEmptyArrayOfBaseItemIdsType" minOccurs="0"/>
+ <!-- Maps to ConversationItemSchema.ConversationGlobalItemIds-->
+ <xs:element name="GlobalItemIds" type="t:NonEmptyArrayOfBaseItemIdsType" minOccurs="0"/>
+
+ <xs:element name="LastModifiedTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="InstanceKey" type="xs:base64Binary" minOccurs="0"/>
+
+ <!-- Maps to ConversationItemSchema.ConversationPreview-->
+ <xs:element name="Preview" type="xs:string" minOccurs="0" />
+
+ <!-- Flag for the mailbox scope this conversation was found in -->
+ <xs:element name="MailboxScope" type="t:MailboxSearchLocationType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationIconIndex-->
+ <xs:element name="IconIndex" type="t:IconIndexType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationGlobalIconIndex-->
+ <xs:element name="GlobalIconIndex" type="t:IconIndexType" minOccurs="0" />
+
+ <!-- Maps to ConversationItemSchema.ConversationDraftItemIds-->
+ <xs:element name="DraftItemIds" type="t:NonEmptyArrayOfBaseItemIdsType" minOccurs="0"/>
+
+ <!-- Maps to ConversationItemSchema.ConversationHasIrm-->
+ <xs:element name="HasIrm" type="xs:boolean" minOccurs="0"/>
+ <!-- Maps to ConversationItemSchema.ConversationGlobalHasIrm-->
+ <xs:element name="GlobalHasIrm" type="xs:boolean" minOccurs="0"/>
+
+ <!-- Maps to ConversationItemSchema.ConversationInferenceClassification-->
+ <xs:element name="InferenceClassification" type="t:InferenceClassificationType" minOccurs="0" />
+
+ <!-- Key on which the data got sorted during search operation-->
+ <xs:element name="SortKey" type="xs:long" minOccurs="0"/>
+
+ <xs:element name="MentionedMe" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="GlobalMentionedMe" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="SenderSMTPAddress" type="t:SmtpAddressType" minOccurs="0"/>
+ <xs:element name="MailboxGuids" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="MailboxGuid" type="t:GuidType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="From" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="AtAllMention" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="GlobalAtAllMention" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="HighlightTermType">
+ <xs:sequence>
+ <xs:element name="Scope" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfConversationsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Conversation" type="t:ConversationType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ConversationRequestType">
+ <xs:sequence>
+ <xs:element name="ConversationId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SyncState" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfConversationRequestsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Conversation" type="t:ConversationRequestType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ConversationNodeType">
+ <xs:sequence>
+ <xs:element name="InternetMessageId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ParentInternetMessageId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Items" type="t:NonEmptyArrayOfAllItemsType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfConversationNodesType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="ConversationNode" type="t:ConversationNodeType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ConversationResponseType">
+ <xs:sequence>
+ <xs:element name="ConversationId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SyncState" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ConversationNodes" type="t:ArrayOfConversationNodesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CanDelete" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="ConversationNodeSortOrder">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="TreeOrderAscending"/>
+ <xs:enumeration value="TreeOrderDescending"/>
+ <xs:enumeration value="DateOrderAscending"/>
+ <xs:enumeration value="DateOrderDescending"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfHighlightTermsType">
+ <xs:sequence>
+ <xs:element name="Term" type="t:HighlightTermType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PersonaAttributionType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SourceId" type="t:ItemIdType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="DisplayName" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="IsWritable" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsQuickContact" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsHidden" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FolderId" type="t:FolderIdType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPersonaAttributionsType">
+ <xs:sequence>
+ <xs:element name="Attribution" type="t:PersonaAttributionType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfValueAttributionsType">
+ <xs:sequence>
+ <xs:element name="Attribution" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfStringValueType">
+ <xs:sequence>
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="StringAttributedValueType">
+ <xs:sequence>
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfValueAttributionsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="BodyContentType">
+ <xs:sequence>
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="BodyType" type="t:BodyTypeType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="BodyContentAttributedValueType">
+ <xs:sequence>
+ <xs:element name="Value" type="t:BodyContentType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfValueAttributionsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="StringArrayAttributedValueType">
+ <xs:sequence>
+ <xs:element name="Values" type="t:ArrayOfStringValueType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfValueAttributionsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EmailAddressAttributedValueType">
+ <xs:sequence>
+ <xs:element name="Value" type="t:EmailAddressType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfValueAttributionsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PersonaPhoneNumberType">
+ <xs:sequence>
+ <xs:element name="Number" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Type" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PhoneNumberAttributedValueType">
+ <xs:sequence>
+ <xs:element name="Value" type="t:PersonaPhoneNumberType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfValueAttributionsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PersonaPostalAddressType">
+ <xs:sequence>
+ <xs:element name="Street" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="City" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="State" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Country" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PostalCode" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PostOfficeBox" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Type" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Latitude" type="xs:double" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Longitude" type="xs:double" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Accuracy" type="xs:double" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Altitude" type="xs:double" minOccurs="0" maxOccurs="1" />
+ <xs:element name="AltitudeAccuracy" type="xs:double" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FormattedAddress" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="LocationUri" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="LocationSource" type="t:LocationSourceType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PostalAddressAttributedValueType">
+ <xs:sequence>
+ <xs:element name="Value" type="t:PersonaPostalAddressType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfValueAttributionsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ExtendedPropertyAttributedValueType">
+ <xs:sequence>
+ <xs:element name="Value" type="t:ExtendedPropertyType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfValueAttributionsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfStringAttributedValuesType">
+ <xs:sequence>
+ <xs:element name="StringAttributedValue" type="t:StringAttributedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfStringArrayAttributedValuesType">
+ <xs:sequence>
+ <xs:element name="StringArrayAttributedValue" type="t:StringArrayAttributedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfBodyContentAttributedValuesType">
+ <xs:sequence>
+ <xs:element name="BodyContentAttributedValue" type="t:BodyContentAttributedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfEmailAddressAttributedValuesType">
+ <xs:sequence>
+ <xs:element name="EmailAddressAttributedValue" type="t:EmailAddressAttributedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPhoneNumberAttributedValuesType">
+ <xs:sequence>
+ <xs:element name="PhoneNumberAttributedValue" type="t:PhoneNumberAttributedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPostalAddressAttributedValuesType">
+ <xs:sequence>
+ <xs:element name="PostalAddressAttributedValue" type="t:PostalAddressAttributedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfExtendedPropertyAttributedValueType">
+ <xs:sequence>
+ <xs:element name="ExtendedPropertyAttributedValue" type="t:ExtendedPropertyAttributedValueType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="InsightFiltersType">
+ <xs:sequence>
+ <xs:element name="Count" type="xs:int" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Types" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="KeyInsightsOnly" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="InsightValue">
+ <xs:sequence>
+ <xs:element name="InsightSource" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="UpdatedUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="StringInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Data" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="DelveDocument">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Rank" type="xs:double" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Author" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Created" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LastModifiedTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DefaultEncodingURL" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="FileType" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Title" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DocumentId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="PreviewURL" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LastEditor" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ProfileInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="FullName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="FirstName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LastName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EmailAddress" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Avatar" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="JoinedUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ProfilePicture" type="t:UserProfilePicture" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Title" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="OutOfOfficeInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="StartTime" type="xs:dateTime" />
+ <xs:element minOccurs="0" maxOccurs="1" name="EndTime" type="xs:dateTime" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Message" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Culture" type="xs:string" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="JobInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Company" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CompanyDescription" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CompanyTicker" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CompanyLogoUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CompanyWebsiteUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CompanyLinkedInUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Title" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="StartUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EndUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="CompanyInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SatoriId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DescriptionAttribution" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ImageUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ImageUrlAttribution" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="YearFound" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="FinanceSymbol" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="WebsiteUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="UserProfilePicture">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Blob" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="PhotoSize" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Url" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ImageType" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="EducationInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Institute" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Degree" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="StartUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EndUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SkillInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Strength" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Subject" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="StartUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EndUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Location" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Organizer" type="t:ProfileInsightValue" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Attendees" type="t:ArrayOfProfileInsightValue" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="EmailInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ThreadId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Subject" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LastEmailDateUtcTicks" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Body" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LastEmailSender" type="t:ProfileInsightValue" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EmailsCount" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfInsightValue">
+ <xs:sequence>
+ <xs:element name="Item" type="t:InsightValue" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSkillInsightValue">
+ <xs:sequence>
+ <xs:element name="Item" type="t:SkillInsightValue" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfProfileInsightValue">
+ <xs:sequence>
+ <xs:element name="Item" type="t:ProfileInsightValue" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfJobInsightValue">
+ <xs:sequence>
+ <xs:element name="Item" type="t:JobInsightValue" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfCompanyInsightValue">
+ <xs:sequence>
+ <xs:element name="Item" type="t:CompanyInsightValue" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="InsightContent">
+ </xs:complexType>
+
+ <xs:complexType name="SingleValueInsightContent">
+ <xs:complexContent>
+ <xs:extension base="t:InsightContent">
+ <xs:sequence>
+ <xs:element name="Item" type="t:InsightValue" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MultiValueInsightContent">
+ <xs:complexContent>
+ <xs:extension base="t:InsightContent">
+ <xs:sequence>
+ <xs:element name="ItemList" type="t:ArrayOfInsightValue" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="Insight">
+ <xs:sequence>
+ <xs:element name="InsightType" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Rank" type="xs:double" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Content" type="t:InsightContent" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Text" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ItemList" type="t:ArrayOfInsightValue" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="RequiresToken" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ComputedInsightValueProperty">
+ <xs:sequence>
+ <xs:element name="Key" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfComputedInsightValueProperty">
+ <xs:sequence>
+ <xs:element name="Property" type="t:ComputedInsightValueProperty" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ComputedInsightValue">
+ <xs:complexContent>
+ <xs:extension base="t:InsightValue">
+ <xs:sequence>
+ <xs:element name="Properties" type="t:ArrayOfComputedInsightValueProperty" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfInsight">
+ <xs:sequence>
+ <xs:element name="Insight" type="t:Insight" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PersonResponseShapeType">
+ <xs:sequence>
+ <xs:element name="BaseShape" type="t:DefaultShapeNamesType" />
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfPathsToElementType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PersonType">
+ <xs:sequence>
+ <xs:element name="FullName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="GivenName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Surname" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PhoneNumber" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SMSNumber" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EmailAddress" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Alias" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Department" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="LinkedInProfileLink" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Skills" type="t:ArrayOfSkillInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ProfessionalBiography" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ManagementChain" type="t:ArrayOfProfileInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DirectReports" type="t:ArrayOfProfileInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Peers" type="t:ArrayOfProfileInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="TeamSize" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CurrentJob" type="t:ArrayOfJobInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Birthday" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Hometown" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CurrentLocation" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CompanyProfile" type="t:ArrayOfCompanyInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Office" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Headline" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MutualConnections" type="t:ArrayOfProfileInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Title" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MutualManager" type="t:ProfileInsightValue" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Insights" type="t:ArrayOfInsight" minOccurs="0" maxOccurs="1" />
+ <xs:element name="UserProfilePicture" type="t:UserProfilePicture" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPersonType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Person" type="t:PersonType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:simpleType name="TokenSourceType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="LinkedIn" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="PeopleTokenType">
+ <xs:sequence>
+ <xs:element name="TokenSource" type="t:TokenSourceType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ExpirationDateTime" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="TokenValue" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfPeopleTokenType">
+ <xs:sequence>
+ <xs:element name="PeopleToken" type="t:PeopleTokenType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PersonaType">
+ <xs:sequence>
+ <xs:element name="PersonaId" type="t:ItemIdType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="PersonaType" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PersonaObjectStatus" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CreationTime" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Bodies" type="t:ArrayOfBodyContentAttributedValuesType" minOccurs="0" />
+ <xs:element name="DisplayNameFirstLastSortKey" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayNameLastFirstSortKey" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CompanyNameSortKey" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="HomeCitySortKey" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="WorkCitySortKey" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayNameFirstLastHeader" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayNameLastFirstHeader" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayNameFirstLast" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayNameLastFirst" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileAs" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileAsId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayNamePrefix" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="GivenName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MiddleName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Surname" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Generation" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Nickname" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="YomiCompanyName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="YomiFirstName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="YomiLastName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Title" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Department" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CompanyName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EmailAddress" type="t:EmailAddressType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EmailAddresses" type="t:ArrayOfEmailAddressesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PhoneNumber" type="t:PersonaPhoneNumberType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ImAddress" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="HomeCity" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="WorkCity" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="RelevanceScore" type="xs:int" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FolderIds" type="t:ArrayOfFolderIdType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Attributions" type="t:ArrayOfPersonaAttributionsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="FileAses" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="FileAsIds" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.DisplayNamePrefix-->
+ <xs:element name="DisplayNamePrefixes" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.GivenName-->
+ <xs:element name="GivenNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.MiddleName-->
+ <xs:element name="MiddleNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Surname-->
+ <xs:element name="Surnames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Generation-->
+ <xs:element name="Generations" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Nickname-->
+ <xs:element name="Nicknames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Initials-->
+ <xs:element name="Initials" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.YomiCompanyName-->
+ <xs:element name="YomiCompanyNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.YomiFirstName-->
+ <xs:element name="YomiFirstNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.YomiLastName-->
+ <xs:element name="YomiLastNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.BusinessPhoneNumber-->
+ <xs:element name="BusinessPhoneNumbers" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.BusinessPhoneNumber2-->
+ <xs:element name="BusinessPhoneNumbers2" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.HomePhone-->
+ <xs:element name="HomePhones" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.HomePhone2-->
+ <xs:element name="HomePhones2" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.MobilePhone-->
+ <xs:element name="MobilePhones" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.MobilePhone2-->
+ <xs:element name="MobilePhones2" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.AssistantPhoneNumber-->
+ <xs:element name="AssistantPhoneNumbers" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.CallbackPhone-->
+ <xs:element name="CallbackPhones" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.CarPhone-->
+ <xs:element name="CarPhones" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.HomeFax-->
+ <xs:element name="HomeFaxes" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.OrganizationMainPhone-->
+ <xs:element name="OrganizationMainPhones" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.OtherFax-->
+ <xs:element name="OtherFaxes" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.OtherTelephone-->
+ <xs:element name="OtherTelephones" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.OtherPhone2-->
+ <xs:element name="OtherPhones2" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Pager-->
+ <xs:element name="Pagers" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.RadioPhone-->
+ <xs:element name="RadioPhones" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.TelexNumber-->
+ <xs:element name="TelexNumbers" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.TTYTDDPhoneNumber-->
+ <xs:element name="TTYTDDPhoneNumbers" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.WorkFax -->
+ <xs:element name="WorkFaxes" type="t:ArrayOfPhoneNumberAttributedValuesType" minOccurs="0" />
+ <!-- Values are aggregation of ContactSchema.Email1AddrType, ContactSchema.Email1DisplayNames, and ContactSchema.Email1EmailAddress-->
+ <xs:element name="Emails1" type="t:ArrayOfEmailAddressAttributedValuesType" minOccurs="0" maxOccurs="1" />
+ <!-- Values are aggregation of ContactSchema.Email2AddrType, ContactSchema.Email2DisplayNames, and ContactSchema.Email2EmailAddress-->
+ <xs:element name="Emails2" type="t:ArrayOfEmailAddressAttributedValuesType" minOccurs="0" maxOccurs="1" />
+ <!-- Values are aggregation of ContactSchema.Email3AddrType, ContactSchema.Email3DisplayNames, and ContactSchema.Email3EmailAddress-->
+ <xs:element name="Emails3" type="t:ArrayOfEmailAddressAttributedValuesType" minOccurs="0" maxOccurs="1" />
+ <!-- Values map to ContactSchema.BusinessHomePage-->
+ <xs:element name="BusinessHomePages" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.PersonalHomePage-->
+ <xs:element name="PersonalHomePages" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.OfficeLocation-->
+ <xs:element name="OfficeLocations" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="ImAddresses" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="ImAddresses2" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="ImAddresses3" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values are aggregation of ContactSchema.WorkAddressStreet/City/State/Country/PostalCode/PostOfficeBox-->
+ <xs:element name="BusinessAddresses" type="t:ArrayOfPostalAddressAttributedValuesType" minOccurs="0" maxOccurs="1" />
+ <!-- Values are aggregation of ContactSchema.HomeStreet/City/State/Country/PostalCode/PostOfficeBox-->
+ <xs:element name="HomeAddresses" type="t:ArrayOfPostalAddressAttributedValuesType" minOccurs="0" maxOccurs="1" />
+ <!-- Values are aggregation of ContactSchema.OtherStreet/City/State/Country/PostalCode/PostOfficeBox-->
+ <xs:element name="OtherAddresses" type="t:ArrayOfPostalAddressAttributedValuesType" minOccurs="0" maxOccurs="1" />
+ <!-- Values map to ContactSchema.Title-->
+ <xs:element name="Titles" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Department-->
+ <xs:element name="Departments" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.CompanyName-->
+ <xs:element name="CompanyNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Manager-->
+ <xs:element name="Managers" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.AssistantName-->
+ <xs:element name="AssistantNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Profession-->
+ <xs:element name="Professions" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.SpouseName-->
+ <xs:element name="SpouseNames" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Children-->
+ <xs:element name="Children" type="t:ArrayOfStringArrayAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Schools-->
+ <xs:element name="Schools" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Hobbies-->
+ <xs:element name="Hobbies" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.WeddingAnniversary-->
+ <xs:element name="WeddingAnniversaries" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Birthday-->
+ <xs:element name="Birthdays" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <!-- Values map to ContactSchema.Location-->
+ <xs:element name="Locations" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="InlineLinks" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="ItemLinkIds" type="t:ArrayOfStringArrayAttributedValuesType" minOccurs="0" />
+ <xs:element name="HasActiveDeals" type="xs:string" minOccurs="0" />
+ <xs:element name="IsBusinessContact" type="xs:string" minOccurs="0" />
+ <xs:element name="AttributedHasActiveDeals" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="AttributedIsBusinessContact" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="SourceMailboxGuids" type="t:ArrayOfStringAttributedValuesType" minOccurs="0" />
+ <xs:element name="LastContactedDate" type="xs:dateTime" minOccurs="0" />
+ <!-- Values map to possibly multiple extended properties -->
+ <xs:element name="ExtendedProperties" type="t:ArrayOfExtendedPropertyAttributedValueType" minOccurs="0" />
+ <xs:element name="ExternalDirectoryObjectId" type="xs:string" minOccurs="0" />
+ <!-- Desktop Outlook properties -->
+ <xs:element name="MapiEntryId" type="xs:string" minOccurs="0" />
+ <xs:element name="MapiEmailAddress" type="xs:string" minOccurs="0" />
+ <xs:element name="MapiAddressType" type="xs:string" minOccurs="0" />
+ <xs:element name="MapiSearchKey" type="xs:string" minOccurs="0" />
+ <xs:element name="MapiTransmittableDisplayName" type="xs:string" minOccurs="0" />
+ <xs:element name="MapiSendRichInfo" type="xs:boolean" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ArrayOfPeopleType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Persona" type="t:PersonaType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxLocatorType">
+ <xs:sequence>
+ <xs:element name="ExternalDirectoryObjectId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="LegacyDn" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="GroupLocatorType">
+ <xs:complexContent>
+ <xs:extension base="t:MailboxLocatorType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="UserLocatorType">
+ <xs:complexContent>
+ <xs:extension base="t:MailboxLocatorType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="GroupMailboxConfigurationActionType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="SetRegionalSettings"/>
+ <xs:enumeration value="CreateDefaultFolders"/>
+ <xs:enumeration value="SetInitialFolderPermissions"/>
+ <xs:enumeration value="SetAllFolderPermissions"/>
+ <xs:enumeration value="ConfigureCalendar"/>
+ <xs:enumeration value="SendWelcomeMessage"/>
+ <xs:enumeration value="GenerateGroupPhoto"/>
+ <xs:enumeration value="AllowOnlyMembersToPost"/>
+ <xs:enumeration value="ConfigureConnectors"/>
+ <xs:enumeration value="ConfigureFileChangeNotification"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="InstantSearchItemType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="MailItem"/>
+ <xs:enumeration value="MailConversation"/>
+ <xs:enumeration value="CalendarItem"/>
+ <xs:enumeration value="Persona"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="InstantSearchResultType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="Suggestions"/>
+ <xs:enumeration value="ItemResults"/>
+ <xs:enumeration value="ConversationResults"/>
+ <xs:enumeration value="Refiners"/>
+ <xs:enumeration value="SearchTerms"/>
+ <xs:enumeration value="Errors"/>
+ <xs:enumeration value="QueryStatistics"/>
+ <xs:enumeration value="CalendarItemResults"/>
+ <xs:enumeration value="PersonaResults"/>
+ <xs:enumeration value="SuggestionsPrimer"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfItemsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Item" type="t:ItemType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfCalendarItemsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="CalendarItem" type="t:CalendarItemType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="InstantSearchPayloadType">
+ <xs:sequence>
+ <xs:element name="SearchSessionId" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SearchRequestId" type="xs:long" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ResultType" type="t:InstantSearchResultType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Items" type="t:ArrayOfItemsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Conversations" type="t:ArrayOfConversationsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CalendarItems" type="t:ArrayOfCalendarItemsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="QueryOptionsType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="Suggestions"/>
+ <xs:enumeration value="Results"/>
+ <xs:enumeration value="Refiners"/>
+ <xs:enumeration value="SearchTerms"/>
+ <xs:enumeration value="ExplicitSearch"/>
+ <xs:enumeration value="SuggestionsPrimer"/>
+ <xs:enumeration value="AllowFuzzing"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="OneDriveViewType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="SharedWithMe"/>
+ <xs:enumeration value="MyDocuments"/>
+ <xs:enumeration value="RecycleBin"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="DelveViewType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="Files"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="GroupMemberIdentifierType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ExternalDirectoryObjectId"/>
+ <xs:enumeration value="LegacyExchangeDN"/>
+ <xs:enumeration value="SmtpAddress"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ModernGroupTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Private" />
+ <xs:enumeration value="Secret" />
+ <xs:enumeration value="Public" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfStringsType">
+ <xs:sequence>
+ <xs:element name="String" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRealItemsType">
+ <xs:sequence>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Item" type="t:ItemType"/>
+ <xs:element name="Message" type="t:MessageType"/>
+ <xs:element name="CalendarItem" type="t:CalendarItemType"/>
+ <xs:element name="Contact" type="t:ContactItemType"/>
+ <xs:element name="DistributionList" type="t:DistributionListType"/>
+ <xs:element name="MeetingMessage" type="t:MeetingMessageType"/>
+ <xs:element name="MeetingRequest" type="t:MeetingRequestMessageType"/>
+ <xs:element name="MeetingResponse" type="t:MeetingResponseMessageType"/>
+ <xs:element name="MeetingCancellation" type="t:MeetingCancellationMessageType"/>
+ <xs:element name="Task" type="t:TaskType"/>
+ <xs:element name="PostItem" type="t:PostItemType"/>
+ <xs:element name="RoleMember" type="t:RoleMemberItemType"/>
+ <xs:element name="Network" type="t:NetworkItemType"/>
+ <xs:element name="Person" type="t:AbchPersonItemType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfAllItemsType">
+ <xs:sequence>
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="Item" type="t:ItemType"/>
+ <xs:element name="Message" type="t:MessageType"/>
+ <xs:element name="CalendarItem" type="t:CalendarItemType"/>
+ <xs:element name="Contact" type="t:ContactItemType"/>
+ <xs:element name="DistributionList" type="t:DistributionListType"/>
+ <xs:element name="MeetingMessage" type="t:MeetingMessageType"/>
+ <xs:element name="MeetingRequest" type="t:MeetingRequestMessageType"/>
+ <xs:element name="MeetingResponse" type="t:MeetingResponseMessageType"/>
+ <xs:element name="MeetingCancellation" type="t:MeetingCancellationMessageType"/>
+ <xs:element name="Task" type="t:TaskType"/>
+ <xs:element name="PostItem" type="t:PostItemType"/>
+ <xs:element name="ReplyToItem" type="t:ReplyToItemType"/>
+ <xs:element name="ForwardItem" type="t:ForwardItemType"/>
+ <xs:element name="ReplyAllToItem" type="t:ReplyAllToItemType"/>
+ <xs:element name="AcceptItem" type="t:AcceptItemType"/>
+ <xs:element name="TentativelyAcceptItem" type="t:TentativelyAcceptItemType"/>
+ <xs:element name="DeclineItem" type="t:DeclineItemType"/>
+ <xs:element name="CancelCalendarItem" type="t:CancelCalendarItemType" />
+ <xs:element name="RemoveItem" type="t:RemoveItemType" />
+ <xs:element name="SuppressReadReceipt" type="t:SuppressReadReceiptType" />
+ <xs:element name="PostReplyItem" type="t:PostReplyItemType" />
+ <xs:element name="AcceptSharingInvitation" type="t:AcceptSharingInvitationType" />
+ <xs:element name="RoleMember" type="t:RoleMemberItemType"/>
+ <xs:element name="Network" type="t:NetworkItemType"/>
+ <xs:element name="Person" type="t:AbchPersonItemType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingRegistrationResponseObjectType">
+ <xs:complexContent>
+ <xs:extension base="t:WellKnownResponseObjectType">
+ <xs:sequence>
+ <xs:element name="ProposedStart" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="ProposedEnd" type="xs:dateTime" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AcceptItemType">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingRegistrationResponseObjectType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="TentativelyAcceptItemType">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingRegistrationResponseObjectType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="DeclineItemType">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingRegistrationResponseObjectType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="ProposeNewTimeType">
+ <xs:complexContent>
+ <xs:extension base="t:ResponseObjectType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="RemoveItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ResponseObjectType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="AddItemToMyCalendarType">
+ <xs:complexContent>
+ <xs:extension base="t:ResponseObjectType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="PostReplyItemBaseType">
+ <xs:complexContent>
+ <xs:restriction base="t:ResponseObjectType">
+ <xs:sequence>
+ <xs:element name="Subject" type="xs:string" minOccurs="0" />
+ <xs:element name="Body" type="t:BodyType" minOccurs="0" />
+ <xs:element name="ReferenceItemId" type="t:ItemIdType" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="ObjectName" type="xs:string" use="prohibited" />
+ </xs:restriction>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="PostReplyItemType">
+ <xs:complexContent>
+ <xs:extension base="t:PostReplyItemBaseType">
+ <xs:sequence>
+ <xs:element name="NewBodyContent" type="t:BodyType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Mime content support -->
+ <xs:complexType name="MimeContentType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="CharacterSet" type="xs:string" use="optional" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Mime content UTF8 support -->
+ <xs:complexType name="MimeContentUTF8Type">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="CharacterSet" type="xs:string" use="optional" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Special items for creating and updating items -->
+
+ <xs:simpleType name="MessageDispositionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="SaveOnly" />
+ <xs:enumeration value="SendOnly" />
+ <xs:enumeration value="SendAndSaveCopy" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="CalendarItemCreateOrDeleteOperationType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="SendToNone" />
+ <xs:enumeration value="SendOnlyToAll" />
+ <xs:enumeration value="SendToAllAndSaveCopy" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="CalendarItemUpdateOperationType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="SendToNone" />
+ <xs:enumeration value="SendOnlyToAll" />
+ <xs:enumeration value="SendOnlyToChanged" />
+ <xs:enumeration value="SendToAllAndSaveCopy" />
+ <xs:enumeration value="SendToChangedAndSaveCopy" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="AffectedTaskOccurrencesType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AllOccurrences"/>
+ <xs:enumeration value="SpecifiedOccurrenceOnly"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- - - - - - - - - - - - - - - - - - - -->
+ <!-- Message type: derived from item -->
+ <!-- - - - - - - - - - - - - - - - - - - -->
+ <xs:complexType name="MessageType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="Sender" minOccurs="0" type="t:SingleRecipientType" />
+ <xs:element name="ToRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="CcRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="BccRecipients" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="IsReadReceiptRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsDeliveryReceiptRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ConversationIndex" type="xs:base64Binary" minOccurs="0" />
+ <xs:element name="ConversationTopic" type="xs:string" minOccurs="0" />
+ <xs:element name="From" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="InternetMessageId" type="xs:string" minOccurs="0" />
+ <xs:element name="IsRead" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsResponseRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="References" type="xs:string" minOccurs="0" />
+ <xs:element name="ReplyTo" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="ReceivedBy" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="ReceivedRepresenting" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="ApprovalRequestData" type="t:ApprovalRequestDataType" minOccurs="0" />
+ <xs:element name="VotingInformation" type="t:VotingInformationType" minOccurs="0" />
+ <xs:element name="ReminderMessageData" type="t:ReminderMessageDataType" minOccurs="0" />
+ <xs:element name="SenderSMTPAddress" type="t:SmtpAddressType" minOccurs="0"/>
+ <xs:element name="MailboxGuids" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="MailboxGuid" type="t:GuidType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="TaskStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NotStarted" />
+ <xs:enumeration value="InProgress" />
+ <xs:enumeration value="Completed" />
+ <xs:enumeration value="WaitingOnOthers" />
+ <xs:enumeration value="Deferred" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="TaskDelegateStateType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NoMatch" />
+ <xs:enumeration value="OwnNew" />
+ <xs:enumeration value="Owned" />
+ <xs:enumeration value="Accepted" />
+ <xs:enumeration value="Declined" />
+ <xs:enumeration value="Max" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="TaskType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="ActualWork" type="xs:int" minOccurs="0" />
+ <xs:element name="AssignedTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="BillingInformation" type="xs:string" minOccurs="0" />
+ <xs:element name="ChangeCount" type="xs:int" minOccurs="0" />
+ <xs:element name="Companies" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="CompleteDate" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="Contacts" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="DelegationState" type="t:TaskDelegateStateType" minOccurs="0" />
+ <xs:element name="Delegator" type="xs:string" minOccurs="0" />
+ <xs:element name="DueDate" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="IsAssignmentEditable" type="xs:int" minOccurs="0" />
+ <xs:element name="IsComplete" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsRecurring" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsTeamTask" type="xs:boolean" minOccurs="0" />
+ <xs:element name="Mileage" type="xs:string" minOccurs="0" />
+ <xs:element name="Owner" type="xs:string" minOccurs="0" />
+ <xs:element name="PercentComplete" type="xs:double" minOccurs="0" />
+ <xs:element name="Recurrence" type="t:TaskRecurrenceType" minOccurs="0" />
+ <xs:element name="StartDate" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="Status" type="t:TaskStatusType" minOccurs="0" />
+ <xs:element name="StatusDescription" type="xs:string" minOccurs="0" />
+ <xs:element name="TotalWork" type="xs:int" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="PostItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="ConversationIndex" type="xs:base64Binary" minOccurs="0"/>
+ <xs:element name="ConversationTopic" type="xs:string" minOccurs="0"/>
+ <!-- From property can only be set at creation time -->
+ <xs:element name="From" type="t:SingleRecipientType" minOccurs="0"/>
+ <xs:element name="InternetMessageId" type="xs:string" minOccurs="0"/>
+ <xs:element name="IsRead" type="xs:boolean" minOccurs="0" />
+ <!-- PostedTime is read only -->
+ <xs:element name="PostedTime" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="References" type="xs:string" minOccurs="0" />
+ <!-- Sender can only be set at creation time -->
+ <xs:element name="Sender" type="t:SingleRecipientType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Paging specification -->
+ <xs:complexType name="BasePagingType" abstract="true">
+ <xs:attribute name="MaxEntriesReturned" type="xs:int" use="optional"/>
+ </xs:complexType>
+
+ <xs:simpleType name="IndexBasePointType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Beginning" />
+ <xs:enumeration value="End" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="IndexedPageViewType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePagingType">
+ <xs:attribute name="Offset" type="xs:int" use="required"/>
+ <xs:attribute name="BasePoint" type="t:IndexBasePointType" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="FractionalPageViewType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePagingType">
+ <xs:attribute name="Numerator" type="xs:int" use="required" />
+ <xs:attribute name="Denominator" type="xs:int" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SeekToConditionPageViewType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePagingType">
+ <xs:sequence>
+ <xs:element name="Condition" type="t:RestrictionType" minOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="BasePoint" type="t:IndexBasePointType" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="CalendarViewType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePagingType">
+ <xs:attribute name="StartDate" type="xs:dateTime" use="required" />
+ <xs:attribute name="EndDate" type="xs:dateTime" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ContactsViewType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePagingType">
+ <xs:attribute name="InitialName" type="xs:string" use="optional"/>
+ <xs:attribute name="FinalName" type="xs:string" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Util Service Types. -->
+
+
+ <!-- ResolveNames request -->
+
+ <xs:simpleType name="ResolveNamesSearchScopeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ActiveDirectory" />
+ <xs:enumeration value="ActiveDirectoryContacts" />
+ <xs:enumeration value="Contacts" />
+ <xs:enumeration value="ContactsActiveDirectory" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- ResolveNames response -->
+
+ <xs:complexType name="ResolutionType">
+ <xs:sequence>
+ <xs:element name="Mailbox" type="t:EmailAddressType" />
+ <xs:element name="Contact" type="t:ContactItemType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfResolutionType">
+ <xs:sequence>
+ <xs:element name="Resolution" type="t:ResolutionType" minOccurs="0" maxOccurs="100" />
+ </xs:sequence>
+ <xs:attributeGroup ref="t:FindResponsePagingAttributes" />
+ </xs:complexType>
+
+ <!-- DLExpansion response -->
+
+ <xs:complexType name="ArrayOfDLExpansionType">
+ <xs:sequence>
+ <xs:element name="Mailbox" type="t:EmailAddressType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attributeGroup ref="t:FindResponsePagingAttributes" />
+ </xs:complexType>
+
+ <!-- end of DLExpansion -->
+
+ <!-- GetServerTimeZones response -->
+
+ <xs:complexType name="NonEmptyArrayOfTimeZoneIdType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfTimeZoneDefinitionType">
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="TimeZoneDefinition" type="t:TimeZoneDefinitionType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- end of GetServerTimeZones -->
+
+
+ <!-- MeetingMessage types -->
+ <xs:simpleType name="MeetingRequestTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="FullUpdate" />
+ <xs:enumeration value="InformationalUpdate" />
+ <xs:enumeration value="NewMeetingRequest" />
+ <xs:enumeration value="Outdated" />
+ <xs:enumeration value="SilentUpdate" />
+ <xs:enumeration value="PrincipalWantsCopy" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- CalendarItem Types -->
+
+ <xs:simpleType name="ReminderMinutesBeforeStartType">
+ <xs:union>
+ <xs:simpleType id="ReminderMinutesBeforeStartType" >
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="0" />
+ <xs:maxInclusive value="2629800" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType id="ReminderMinutesBeforeStartMarkerType">
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="1525252321" />
+ <xs:maxInclusive value="1525252321" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:union>
+ </xs:simpleType>
+
+ <!-- Enumeration types -->
+ <xs:simpleType name="AvailabilityStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Unknown" />
+ <xs:enumeration value="Free" />
+ <xs:enumeration value="Tentative" />
+ <xs:enumeration value="Busy" />
+ <xs:enumeration value="Oof" />
+ <xs:enumeration value="WorkingElsewhere" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="LegacyFreeBusyType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Free" />
+ <xs:enumeration value="Tentative" />
+ <xs:enumeration value="Busy" />
+ <xs:enumeration value="OOF" />
+ <xs:enumeration value="WorkingElsewhere" />
+ <xs:enumeration value="NoData" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="CalendarItemTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Single" />
+ <xs:enumeration value="Occurrence" />
+ <xs:enumeration value="Exception" />
+ <xs:enumeration value="RecurringMaster" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ResponseTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Unknown" />
+ <xs:enumeration value="Organizer" />
+ <xs:enumeration value="Tentative" />
+ <xs:enumeration value="Accept" />
+ <xs:enumeration value="Decline" />
+ <xs:enumeration value="NoResponseReceived" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Online Meeting type and enums -->
+
+ <xs:complexType name="OnlineMeetingSettingsType">
+ <xs:sequence>
+ <xs:element name="LobbyBypass" type="t:LobbyBypassType" />
+ <xs:element name="AccessLevel" type="t:OnlineMeetingAccessLevelType" />
+ <xs:element name="Presenters" type="t:PresentersType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="LobbyBypassType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Disabled" />
+ <xs:enumeration value="EnabledForGatewayParticipants" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="OnlineMeetingAccessLevelType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Locked" />
+ <xs:enumeration value="Invited" />
+ <xs:enumeration value="Internal" />
+ <xs:enumeration value="Everyone" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="PresentersType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Disabled" />
+ <xs:enumeration value="Internal" />
+ <xs:enumeration value="Everyone" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Representation of attendees -->
+
+ <xs:complexType name="AttendeeType">
+ <xs:sequence>
+ <xs:element name="Mailbox" type="t:EmailAddressType" />
+ <xs:element name="ResponseType" type="t:ResponseTypeType" minOccurs="0" />
+ <xs:element name="LastResponseTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="ProposedStart" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="ProposedEnd" type="xs:dateTime" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfAttendeesType">
+ <xs:sequence>
+ <xs:element name="Attendee" type="t:AttendeeType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Special item ids for interconverting between instances and masters -->
+
+ <xs:complexType name="OccurrenceItemIdType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseItemIdType">
+ <xs:attribute name="RecurringMasterId" type="t:DerivedItemIdType" use="required" />
+ <xs:attribute name="ChangeKey" type="xs:string" use="optional" />
+ <xs:attribute name="InstanceIndex" type="xs:int" use="required" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="RecurringMasterItemIdType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseItemIdType">
+ <xs:attribute name="OccurrenceId" type="t:DerivedItemIdType" use="required" />
+ <xs:attribute name="ChangeKey" type="xs:string" use="optional" />
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="RecurringMasterItemIdRangesType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemIdType">
+ <xs:sequence>
+ <xs:element name="Ranges" type="t:ArrayOfOccurrenceRangesType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfOccurrenceRangesType">
+ <xs:sequence>
+ <xs:element name="Range" type="t:OccurrencesRangeType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="OccurrencesRangeType">
+ <xs:attribute name="Start" type="xs:dateTime" use="optional" />
+ <xs:attribute name="End" type="xs:dateTime" use="optional" />
+ <xs:attribute name="Count" type="xs:int" use="optional" />
+ <xs:attribute name="CompareOriginalStartTime" type="xs:boolean" use="optional" />
+ </xs:complexType>
+
+ <!-- Days of the week and months-->
+
+ <xs:simpleType name="DayOfWeekType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Sunday" />
+ <xs:enumeration value="Monday" />
+ <xs:enumeration value="Tuesday" />
+ <xs:enumeration value="Wednesday" />
+ <xs:enumeration value="Thursday" />
+ <xs:enumeration value="Friday" />
+ <xs:enumeration value="Saturday" />
+ <xs:enumeration value="Day" />
+ <xs:enumeration value="Weekday" />
+ <xs:enumeration value="WeekendDay" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="DaysOfWeekType">
+ <xs:list itemType="t:DayOfWeekType" />
+ </xs:simpleType>
+
+ <xs:simpleType name="DayOfWeekIndexType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="First" />
+ <xs:enumeration value="Second" />
+ <xs:enumeration value="Third" />
+ <xs:enumeration value="Fourth" />
+ <xs:enumeration value="Last" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="MonthNamesType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="January" />
+ <xs:enumeration value="February" />
+ <xs:enumeration value="March" />
+ <xs:enumeration value="April" />
+ <xs:enumeration value="May" />
+ <xs:enumeration value="June" />
+ <xs:enumeration value="July" />
+ <xs:enumeration value="August" />
+ <xs:enumeration value="September" />
+ <xs:enumeration value="October" />
+ <xs:enumeration value="November" />
+ <xs:enumeration value="December" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Recurrence pattern types -->
+
+ <xs:complexType name="RecurrencePatternBaseType" abstract="true" />
+
+ <xs:complexType name="IntervalRecurrencePatternBaseType" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="t:RecurrencePatternBaseType">
+ <xs:sequence>
+ <xs:element name="Interval" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!--
+ Base regeneration pattern type for tasks.
+ -->
+
+ <xs:complexType name="RegeneratingPatternBaseType" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="t:IntervalRecurrencePatternBaseType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="DailyRegeneratingPatternType">
+ <xs:complexContent>
+ <xs:extension base="t:RegeneratingPatternBaseType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="WeeklyRegeneratingPatternType">
+ <xs:complexContent>
+ <xs:extension base="t:RegeneratingPatternBaseType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MonthlyRegeneratingPatternType">
+ <xs:complexContent>
+ <xs:extension base="t:RegeneratingPatternBaseType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="YearlyRegeneratingPatternType">
+ <xs:complexContent>
+ <xs:extension base="t:RegeneratingPatternBaseType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Realizable Recurrence pattern types -->
+
+ <xs:complexType name="RelativeYearlyRecurrencePatternType">
+ <xs:complexContent>
+ <xs:extension base="t:RecurrencePatternBaseType">
+ <xs:sequence>
+ <xs:element name="DaysOfWeek" type="t:DayOfWeekType" />
+ <xs:element name="DayOfWeekIndex" type="t:DayOfWeekIndexType" />
+ <xs:element name="Month" type="t:MonthNamesType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AbsoluteYearlyRecurrencePatternType">
+ <xs:complexContent>
+ <xs:extension base="t:RecurrencePatternBaseType">
+ <xs:sequence>
+ <xs:element name="DayOfMonth" type="xs:int" />
+ <xs:element name="Month" type="t:MonthNamesType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="RelativeMonthlyRecurrencePatternType">
+ <xs:complexContent>
+ <xs:extension base="t:IntervalRecurrencePatternBaseType">
+ <xs:sequence>
+ <xs:element name="DaysOfWeek" type="t:DayOfWeekType" />
+ <xs:element name="DayOfWeekIndex" type="t:DayOfWeekIndexType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AbsoluteMonthlyRecurrencePatternType">
+ <xs:complexContent>
+ <xs:extension base="t:IntervalRecurrencePatternBaseType">
+ <xs:sequence>
+ <xs:element name="DayOfMonth" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="WeeklyRecurrencePatternType">
+ <xs:complexContent>
+ <xs:extension base="t:IntervalRecurrencePatternBaseType">
+ <xs:sequence>
+ <xs:element name="DaysOfWeek" type="t:DaysOfWeekType"/>
+ <xs:element name="FirstDayOfWeek" type="t:DayOfWeekType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="DailyRecurrencePatternType">
+ <xs:complexContent>
+ <xs:extension base="t:IntervalRecurrencePatternBaseType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Enhanced location types -->
+ <xs:simpleType name="LocationSourceType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="LocationServices" />
+ <xs:enumeration value="PhonebookServices" />
+ <xs:enumeration value="Device" />
+ <xs:enumeration value="Contact" />
+ <xs:enumeration value="Resource" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="EnhancedLocationType">
+ <xs:sequence>
+ <xs:element name="DisplayName" type="xs:string" />
+ <xs:element name="Annotation" type="xs:string" minOccurs="0" />
+ <xs:element name="PostalAddress" type="t:PersonaPostalAddressType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Description of a time zone -->
+
+ <xs:group name="TimeChangePatternTypes">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="RelativeYearlyRecurrence" type="t:RelativeYearlyRecurrencePatternType" />
+ <xs:element name="AbsoluteDate" type="xs:date" />
+ </xs:choice>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:complexType name="TimeChangeType">
+ <xs:sequence>
+ <xs:element name="Offset" type="xs:duration" />
+ <xs:group ref="t:TimeChangePatternTypes" minOccurs="0"/>
+ <xs:element name="Time" type="xs:time" />
+ </xs:sequence>
+ <xs:attribute name="TimeZoneName" type="xs:string" use="optional" />
+ </xs:complexType>
+
+ <xs:complexType name="TimeZoneType">
+ <xs:sequence minOccurs="0" >
+ <xs:element name="BaseOffset" type="xs:duration" />
+ <xs:sequence minOccurs="0">
+ <xs:element name="Standard" type="t:TimeChangeType"/>
+ <xs:element name="Daylight" type="t:TimeChangeType"/>
+ </xs:sequence>
+ </xs:sequence>
+ <xs:attribute name="TimeZoneName" type="xs:string" use="optional" />
+ </xs:complexType>
+
+ <!-- TimeZoneDefinitionContextType for Soap header -->
+
+ <xs:complexType name="TimeZoneContextType">
+ <xs:sequence>
+ <xs:element name="TimeZoneDefinition" type="t:TimeZoneDefinitionType" minOccurs="1"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="http://schemas.xmlsoap.org/soap/envelope/">
+ <xs:annotation>
+ <xs:documentation>Allow attributes in the soap namespace to be used here</xs:documentation>
+ </xs:annotation>
+ </xs:anyAttribute>
+ </xs:complexType>
+
+
+ <xs:element name="TimeZoneContext" type="t:TimeZoneContextType" />
+
+ <!-- Time zone definition types -->
+
+ <xs:simpleType name="TransitionTargetKindType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Period" />
+ <xs:enumeration value="Group" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="TransitionTargetType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string" >
+ <xs:attribute name="Kind" type="t:TransitionTargetKindType" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="TransitionType" abstract="false">
+ <xs:sequence>
+ <xs:element name="To" type="t:TransitionTargetType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AbsoluteDateTransitionType">
+ <xs:complexContent>
+ <xs:extension base="t:TransitionType">
+ <xs:sequence>
+ <xs:element name="DateTime" type="xs:dateTime" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="RecurringTimeTransitionType" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="t:TransitionType">
+ <xs:sequence>
+ <xs:element name="TimeOffset" type="xs:duration" />
+ <xs:element name="Month" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="RecurringDateTransitionType">
+ <xs:complexContent>
+ <xs:extension base="t:RecurringTimeTransitionType">
+ <xs:sequence>
+ <xs:element name="Day" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="RecurringDayTransitionType">
+ <xs:complexContent>
+ <xs:extension base="t:RecurringTimeTransitionType">
+ <xs:sequence>
+ <xs:element name="DayOfWeek" type="t:DayOfWeekType" />
+ <xs:element name="Occurrence" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="Transition" type="t:TransitionType" />
+ <xs:element name="AbsoluteDateTransition" type="t:AbsoluteDateTransitionType" substitutionGroup="t:Transition"/>
+ <xs:element name="RecurringDayTransition" type="t:RecurringDayTransitionType" substitutionGroup="t:Transition"/>
+ <xs:element name="RecurringDateTransition" type="t:RecurringDateTransitionType" substitutionGroup="t:Transition"/>
+
+ <!-- TimeZoneDefinition -->
+
+ <xs:complexType name="TimeZoneDefinitionType">
+ <xs:sequence minOccurs="0">
+ <xs:element name="Periods" type="t:NonEmptyArrayOfPeriodsType" minOccurs="0" />
+ <xs:element name="TransitionsGroups" type="t:ArrayOfTransitionsGroupsType" minOccurs="0"/>
+ <xs:element name="Transitions" type="t:ArrayOfTransitionsType" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="Id" type="xs:string"/>
+ <xs:attribute name="Name" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfPeriodsType">
+ <xs:sequence>
+ <xs:element name="Period" type="t:PeriodType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PeriodType">
+ <xs:attribute name="Bias" type="xs:duration"/>
+ <xs:attribute name="Name" type="xs:string"/>
+ <xs:attribute name="Id" type="xs:string"/>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfTransitionsGroupsType">
+ <xs:sequence>
+ <xs:element name="TransitionsGroup" type="t:ArrayOfTransitionsType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfTransitionsType">
+ <xs:sequence>
+ <xs:element ref="t:AbsoluteDateTransition" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="t:RecurringDayTransition" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="t:RecurringDateTransition" minOccurs="0" maxOccurs="unbounded" />
+ <xs:element ref="t:Transition" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="Id" type="xs:string"/>
+ </xs:complexType>
+
+ <!-- Recurrence range types -->
+
+ <xs:complexType name="RecurrenceRangeBaseType" abstract="true">
+ <xs:sequence>
+ <xs:element name="StartDate" type="xs:date" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NoEndRecurrenceRangeType">
+ <xs:complexContent>
+ <xs:extension base="t:RecurrenceRangeBaseType" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="EndDateRecurrenceRangeType">
+ <xs:complexContent>
+ <xs:extension base="t:RecurrenceRangeBaseType">
+ <xs:sequence>
+ <xs:element name="EndDate" type="xs:date" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NumberedRecurrenceRangeType">
+ <xs:complexContent>
+ <xs:extension base="t:RecurrenceRangeBaseType">
+ <xs:sequence>
+ <xs:element name="NumberOfOccurrences" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- The real Recurrence type -->
+
+ <xs:group name="RecurrencePatternTypes">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="RelativeYearlyRecurrence" type="t:RelativeYearlyRecurrencePatternType" />
+ <xs:element name="AbsoluteYearlyRecurrence" type="t:AbsoluteYearlyRecurrencePatternType" />
+ <xs:element name="RelativeMonthlyRecurrence" type="t:RelativeMonthlyRecurrencePatternType" />
+ <xs:element name="AbsoluteMonthlyRecurrence" type="t:AbsoluteMonthlyRecurrencePatternType" />
+ <xs:element name="WeeklyRecurrence" type="t:WeeklyRecurrencePatternType" />
+ <xs:element name="DailyRecurrence" type="t:DailyRecurrencePatternType" />
+ </xs:choice>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="TaskRecurrencePatternTypes">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="RelativeYearlyRecurrence" type="t:RelativeYearlyRecurrencePatternType"/>
+ <xs:element name="AbsoluteYearlyRecurrence" type="t:AbsoluteYearlyRecurrencePatternType"/>
+ <xs:element name="RelativeMonthlyRecurrence" type="t:RelativeMonthlyRecurrencePatternType"/>
+ <xs:element name="AbsoluteMonthlyRecurrence" type="t:AbsoluteMonthlyRecurrencePatternType"/>
+ <xs:element name="WeeklyRecurrence" type="t:WeeklyRecurrencePatternType"/>
+ <xs:element name="DailyRecurrence" type="t:DailyRecurrencePatternType"/>
+ <xs:element name="DailyRegeneration" type="t:DailyRegeneratingPatternType"/>
+ <xs:element name="WeeklyRegeneration" type="t:WeeklyRegeneratingPatternType"/>
+ <xs:element name="MonthlyRegeneration" type="t:MonthlyRegeneratingPatternType"/>
+ <xs:element name="YearlyRegeneration" type="t:YearlyRegeneratingPatternType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:group name="RecurrenceRangeTypes">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="NoEndRecurrence" type="t:NoEndRecurrenceRangeType" />
+ <xs:element name="EndDateRecurrence" type="t:EndDateRecurrenceRangeType" />
+ <xs:element name="NumberedRecurrence" type="t:NumberedRecurrenceRangeType" />
+ </xs:choice>
+ </xs:sequence>
+ </xs:group>
+
+ <xs:complexType name="RecurrenceType">
+ <xs:sequence>
+ <xs:group ref="t:RecurrencePatternTypes" />
+ <xs:group ref="t:RecurrenceRangeTypes" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="TaskRecurrenceType">
+ <xs:sequence>
+ <xs:group ref="t:TaskRecurrencePatternTypes"/>
+ <xs:group ref="t:RecurrenceRangeTypes"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Individual occurrences of an expanded Recurrence -->
+
+ <xs:complexType name="OccurrenceInfoType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" />
+ <xs:element name="Start" type="xs:dateTime" />
+ <xs:element name="End" type="xs:dateTime" />
+ <xs:element name="OriginalStart" type="xs:dateTime" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfOccurrenceInfoType">
+ <xs:sequence>
+ <xs:element name="Occurrence" type="t:OccurrenceInfoType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DeletedOccurrenceInfoType">
+ <xs:sequence>
+ <xs:element name="Start" type="xs:dateTime" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfDeletedOccurrencesType">
+ <xs:sequence>
+ <xs:element name="DeletedOccurrence" type="t:DeletedOccurrenceInfoType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- The main calendar item from which all others derive -->
+
+ <xs:complexType name="CalendarItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+
+ <!-- iCalendar properties -->
+
+ <xs:element name="UID" type="xs:string" minOccurs="0" />
+ <xs:element name="RecurrenceId" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="DateTimeStamp" type="xs:dateTime" minOccurs="0" />
+
+ <!-- Single and Occurrence only -->
+
+ <xs:element name="Start" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="End" type="xs:dateTime" minOccurs="0" />
+
+ <!-- Occurrence only -->
+
+ <xs:element name="OriginalStart" type="xs:dateTime" minOccurs="0" />
+
+ <xs:element name="IsAllDayEvent" type="xs:boolean" minOccurs="0" />
+ <xs:element name="LegacyFreeBusyStatus" type="t:LegacyFreeBusyType" minOccurs="0" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" />
+ <xs:element name="When" type="xs:string" minOccurs="0" />
+ <xs:element name="IsMeeting" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsCancelled" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsRecurring" type="xs:boolean" minOccurs="0" />
+ <xs:element name="MeetingRequestWasSent" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsResponseRequested" type="xs:boolean" minOccurs="0" />
+ <xs:element name="CalendarItemType" type="t:CalendarItemTypeType" minOccurs="0" />
+ <xs:element name="MyResponseType" type="t:ResponseTypeType" minOccurs="0" />
+ <xs:element name="Organizer" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="RequiredAttendees" type="t:NonEmptyArrayOfAttendeesType" minOccurs="0" />
+ <xs:element name="OptionalAttendees" type="t:NonEmptyArrayOfAttendeesType" minOccurs="0" />
+ <xs:element name="Resources" type="t:NonEmptyArrayOfAttendeesType" minOccurs="0" />
+ <xs:element name="InboxReminders" type="t:ArrayOfInboxReminderType" minOccurs="0" />
+
+ <!-- Conflicting and adjacent meetings -->
+
+ <xs:element name="ConflictingMeetingCount" type="xs:int" minOccurs="0" />
+ <xs:element name="AdjacentMeetingCount" type="xs:int" minOccurs="0" />
+ <xs:element name="ConflictingMeetings" type="t:NonEmptyArrayOfAllItemsType" minOccurs="0" />
+ <xs:element name="AdjacentMeetings" type="t:NonEmptyArrayOfAllItemsType" minOccurs="0" />
+
+ <xs:element name="Duration" type="xs:string" minOccurs="0" />
+ <xs:element name="TimeZone" type="xs:string" minOccurs="0" />
+
+ <xs:element name="AppointmentReplyTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="AppointmentSequenceNumber" type="xs:int" minOccurs="0" />
+ <xs:element name="AppointmentState" type="xs:int" minOccurs="0" />
+
+ <!-- Recurrence specific data, only valid if CalendarItemType is RecurringMaster -->
+
+ <xs:element name="Recurrence" type="t:RecurrenceType" minOccurs="0" />
+ <xs:element name="FirstOccurrence" type="t:OccurrenceInfoType" minOccurs="0" />
+ <xs:element name="LastOccurrence" type="t:OccurrenceInfoType" minOccurs="0" />
+ <xs:element name="ModifiedOccurrences" type="t:NonEmptyArrayOfOccurrenceInfoType" minOccurs="0" />
+ <xs:element name="DeletedOccurrences" type="t:NonEmptyArrayOfDeletedOccurrencesType" minOccurs="0" />
+ <xs:element name="MeetingTimeZone" type="t:TimeZoneType" minOccurs="0"/>
+ <xs:element name="StartTimeZone" type="t:TimeZoneDefinitionType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndTimeZone" type="t:TimeZoneDefinitionType" minOccurs="0" maxOccurs="1" />
+
+ <xs:element name="ConferenceType" type="xs:int" minOccurs="0" />
+ <xs:element name="AllowNewTimeProposal" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsOnlineMeeting" type="xs:boolean" minOccurs="0" />
+ <xs:element name="MeetingWorkspaceUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="NetShowUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="EnhancedLocation" type="t:EnhancedLocationType" minOccurs="0" />
+
+ <xs:element name="StartWallClock" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndWallClock" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="StartTimeZoneId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndTimeZoneId" type="xs:string" minOccurs="0" maxOccurs="1" />
+
+ <xs:element name="IntendedFreeBusyStatus" type="t:LegacyFreeBusyType" minOccurs="0" />
+
+ <xs:element name="JoinOnlineMeetingUrl" type="xs:string" minOccurs="0" maxOccurs="1" />
+
+ <xs:element name="OnlineMeetingSettings" type="t:OnlineMeetingSettingsType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IsOrganizer" type="xs:boolean" minOccurs="0" />
+ <xs:element name="CalendarActivityData" type="t:CalendarActivityDataType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Getting occurrences from Recurring masters and vice versa -->
+
+ <!--Meeting invitation-->
+
+ <xs:complexType name="MeetingMessageType">
+ <xs:complexContent>
+ <xs:extension base="t:MessageType">
+ <xs:sequence>
+ <xs:element name="AssociatedCalendarItemId" type="t:ItemIdType" minOccurs="0"/>
+ <xs:element name="IsDelegated" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsOutOfDate" type="xs:boolean" minOccurs="0" />
+ <xs:element name="HasBeenProcessed" type="xs:boolean" minOccurs="0" />
+
+ <!-- Meeting response related properties -->
+
+ <xs:element name="ResponseType" type="t:ResponseTypeType" minOccurs="0" />
+
+ <!-- iCalendar properties -->
+
+ <xs:element name="UID" type="xs:string" minOccurs="0" />
+ <xs:element name="RecurrenceId" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="DateTimeStamp" type="xs:dateTime" minOccurs="0" />
+
+ <xs:element name="IsOrganizer" type="xs:boolean" minOccurs="0" />
+
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!--ChangeHighlights-->
+ <xs:complexType name="ChangeHighlightsType">
+ <xs:sequence>
+ <xs:element name="HasLocationChanged" type="xs:boolean" minOccurs="0" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" />
+ <xs:element name="HasStartTimeChanged" type="xs:boolean" minOccurs="0" />
+ <xs:element name="Start" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="HasEndTimeChanged" type="xs:boolean" minOccurs="0" />
+ <xs:element name="End" type="xs:dateTime" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingRequestMessageType">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingMessageType">
+ <xs:sequence>
+ <!--- MeetingRequest properties -->
+
+ <xs:element name="MeetingRequestType" type="t:MeetingRequestTypeType" minOccurs="0" />
+ <xs:element name="IntendedFreeBusyStatus" type="t:LegacyFreeBusyType" minOccurs="0" />
+
+ <!-- Calendar Properties of the associated meeting request -->
+
+ <!-- Single and Occurrence only -->
+
+ <xs:element name="Start" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="End" type="xs:dateTime" minOccurs="0" />
+
+ <!-- Occurrence only -->
+
+ <xs:element name="OriginalStart" type="xs:dateTime" minOccurs="0" />
+
+ <xs:element name="IsAllDayEvent" type="xs:boolean" minOccurs="0" />
+ <xs:element name="LegacyFreeBusyStatus" type="t:LegacyFreeBusyType" minOccurs="0" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" />
+ <xs:element name="When" type="xs:string" minOccurs="0" />
+ <xs:element name="IsMeeting" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsCancelled" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsRecurring" type="xs:boolean" minOccurs="0" />
+ <xs:element name="MeetingRequestWasSent" type="xs:boolean" minOccurs="0" />
+ <xs:element name="CalendarItemType" type="t:CalendarItemTypeType" minOccurs="0" />
+ <xs:element name="MyResponseType" type="t:ResponseTypeType" minOccurs="0" />
+ <xs:element name="Organizer" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="RequiredAttendees" type="t:NonEmptyArrayOfAttendeesType" minOccurs="0" />
+ <xs:element name="OptionalAttendees" type="t:NonEmptyArrayOfAttendeesType" minOccurs="0" />
+ <xs:element name="Resources" type="t:NonEmptyArrayOfAttendeesType" minOccurs="0" />
+
+ <!-- Conflicting and adjacent meetings -->
+
+ <xs:element name="ConflictingMeetingCount" type="xs:int" minOccurs="0" />
+ <xs:element name="AdjacentMeetingCount" type="xs:int" minOccurs="0" />
+ <xs:element name="ConflictingMeetings" type="t:NonEmptyArrayOfAllItemsType" minOccurs="0" />
+ <xs:element name="AdjacentMeetings" type="t:NonEmptyArrayOfAllItemsType" minOccurs="0" />
+
+ <xs:element name="Duration" type="xs:string" minOccurs="0" />
+ <xs:element name="TimeZone" type="xs:string" minOccurs="0" />
+
+ <xs:element name="AppointmentReplyTime" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="AppointmentSequenceNumber" type="xs:int" minOccurs="0" />
+ <xs:element name="AppointmentState" type="xs:int" minOccurs="0" />
+
+ <!-- Recurrence specific data, only valid if CalendarItemType is RecurringMaster -->
+
+ <xs:element name="Recurrence" type="t:RecurrenceType" minOccurs="0" />
+ <xs:element name="FirstOccurrence" type="t:OccurrenceInfoType" minOccurs="0" />
+ <xs:element name="LastOccurrence" type="t:OccurrenceInfoType" minOccurs="0" />
+ <xs:element name="ModifiedOccurrences" type="t:NonEmptyArrayOfOccurrenceInfoType" minOccurs="0" />
+ <xs:element name="DeletedOccurrences" type="t:NonEmptyArrayOfDeletedOccurrencesType" minOccurs="0" />
+ <xs:element name="MeetingTimeZone" type="t:TimeZoneType" minOccurs="0" />
+ <xs:element name="StartTimeZone" type="t:TimeZoneDefinitionType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndTimeZone" type="t:TimeZoneDefinitionType" minOccurs="0" maxOccurs="1" />
+
+ <xs:element name="ConferenceType" type="xs:int" minOccurs="0" />
+ <xs:element name="AllowNewTimeProposal" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsOnlineMeeting" type="xs:boolean" minOccurs="0" />
+ <xs:element name="MeetingWorkspaceUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="NetShowUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="EnhancedLocation" type="t:EnhancedLocationType" minOccurs="0" />
+ <xs:element name="ChangeHighlights" type="t:ChangeHighlightsType" minOccurs="0" />
+
+ <xs:element name="StartWallClock" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndWallClock" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="StartTimeZoneId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndTimeZoneId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingResponseMessageType">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingMessageType">
+ <xs:sequence>
+ <xs:element name="Start" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="End" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" />
+ <xs:element name="Recurrence" type="t:RecurrenceType" minOccurs="0" />
+ <xs:element name="CalendarItemType" type="xs:string" minOccurs="0" />
+ <xs:element name="ProposedStart" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="ProposedEnd" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="EnhancedLocation" type="t:EnhancedLocationType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingCancellationMessageType">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingMessageType">
+ <xs:sequence>
+ <xs:element name="Start" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="End" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="Location" type="xs:string" minOccurs="0" />
+ <xs:element name="Recurrence" type="t:RecurrenceType" minOccurs="0" />
+ <xs:element name="CalendarItemType" type="xs:string" minOccurs="0" />
+ <xs:element name="EnhancedLocation" type="t:EnhancedLocationType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- End of CalendarItem Types -->
+
+ <!-- Contacts Types -->
+
+ <xs:simpleType name="RoleMemberTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Passport" />
+ <xs:enumeration value="Everyone" />
+ <xs:enumeration value="Email" />
+ <xs:enumeration value="Phone" />
+ <xs:enumeration value="SkypeId" />
+ <xs:enumeration value="ExternalId" />
+ <xs:enumeration value="Group" />
+ <xs:enumeration value="Guid" />
+ <xs:enumeration value="Role" />
+ <xs:enumeration value="Service" />
+ <xs:enumeration value="Circle" />
+ <xs:enumeration value="Domain" />
+ <xs:enumeration value="Partner" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ImAddressKeyType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ImAddress1" />
+ <xs:enumeration value="ImAddress2" />
+ <xs:enumeration value="ImAddress3" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="EmailAddressKeyType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="EmailAddress1" />
+ <xs:enumeration value="EmailAddress2" />
+ <xs:enumeration value="EmailAddress3" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="AbchEmailAddressTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Personal" />
+ <xs:enumeration value="Business" />
+ <xs:enumeration value="Other" />
+ <xs:enumeration value="Passport" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ContactUrlKeyType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Personal" />
+ <xs:enumeration value="Business" />
+ <xs:enumeration value="Attachment" />
+ <xs:enumeration value="EbcDisplayDefinition" />
+ <xs:enumeration value="EbcFinalImage" />
+ <xs:enumeration value="EbcLogo" />
+ <xs:enumeration value="Feed" />
+ <xs:enumeration value="Image" />
+ <xs:enumeration value="InternalMarker" />
+ <xs:enumeration value="Other" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="PhoneNumberKeyType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AssistantPhone" />
+ <xs:enumeration value="BusinessFax" />
+ <xs:enumeration value="BusinessPhone" />
+ <xs:enumeration value="BusinessPhone2" />
+ <xs:enumeration value="Callback" />
+ <xs:enumeration value="CarPhone" />
+ <xs:enumeration value="CompanyMainPhone" />
+ <xs:enumeration value="HomeFax" />
+ <xs:enumeration value="HomePhone" />
+ <xs:enumeration value="HomePhone2" />
+ <xs:enumeration value="Isdn" />
+ <xs:enumeration value="MobilePhone" />
+ <xs:enumeration value="OtherFax" />
+ <xs:enumeration value="OtherTelephone" />
+ <xs:enumeration value="Pager" />
+ <xs:enumeration value="PrimaryPhone" />
+ <xs:enumeration value="RadioPhone" />
+ <xs:enumeration value="Telex" />
+ <xs:enumeration value="TtyTddPhone" />
+ <xs:enumeration value="BusinessMobile" />
+ <xs:enumeration value="IPPhone" />
+ <xs:enumeration value="Mms" />
+ <xs:enumeration value="Msn" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="PhysicalAddressIndexType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Home" />
+ <xs:enumeration value="Business" />
+ <xs:enumeration value="Other" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="PhysicalAddressKeyType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Home" />
+ <xs:enumeration value="Business" />
+ <xs:enumeration value="Other" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="FileAsMappingType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="LastCommaFirst" />
+ <xs:enumeration value="FirstSpaceLast" />
+ <xs:enumeration value="Company" />
+ <xs:enumeration value="LastCommaFirstCompany" />
+ <xs:enumeration value="CompanyLastFirst" />
+ <xs:enumeration value="LastFirst" />
+ <xs:enumeration value="LastFirstCompany" />
+ <xs:enumeration value="CompanyLastCommaFirst" />
+ <xs:enumeration value="LastFirstSuffix" />
+ <xs:enumeration value="LastSpaceFirstCompany" />
+ <xs:enumeration value="CompanyLastSpaceFirst" />
+ <xs:enumeration value="LastSpaceFirst" />
+ <xs:enumeration value="DisplayName" />
+ <xs:enumeration value="FirstName" />
+ <xs:enumeration value="LastFirstMiddleSuffix" />
+ <xs:enumeration value="LastName" />
+ <xs:enumeration value="Empty" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Contact source -->
+
+ <xs:simpleType name="ContactSourceType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ActiveDirectory" />
+ <xs:enumeration value="Store" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- complete name for a contact -->
+
+ <xs:complexType name="CompleteNameType">
+ <xs:sequence>
+ <xs:element name="Title" type="xs:string" minOccurs="0" />
+ <xs:element name="FirstName" type="xs:string" minOccurs="0" />
+ <xs:element name="MiddleName" type="xs:string" minOccurs="0" />
+ <xs:element name="LastName" type="xs:string" minOccurs="0" />
+ <xs:element name="Suffix" type="xs:string" minOccurs="0" />
+ <xs:element name="Initials" type="xs:string" minOccurs="0" />
+ <xs:element name="FullName" type="xs:string" minOccurs="0" />
+ <xs:element name="Nickname" type="xs:string" minOccurs="0" />
+ <xs:element name="YomiFirstName" type="xs:string" minOccurs="0" />
+ <xs:element name="YomiLastName" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Dictionary types for items -->
+
+ <xs:complexType name="ImAddressDictionaryEntryType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Key" type="t:ImAddressKeyType" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+
+ <xs:complexType name="ContactUrlDictionaryEntryType">
+ <xs:sequence>
+ <xs:element name="Type" type="t:ContactUrlKeyType" minOccurs="1" />
+ <xs:element name="Name" type="xs:string" minOccurs="0" />
+ <xs:element name="Address" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AbchEmailAddressDictionaryEntryType">
+ <xs:sequence>
+ <xs:element name="Type" type="t:AbchEmailAddressTypeType" minOccurs="1" />
+ <xs:element name="Address" type="xs:string" minOccurs="1" />
+ <xs:element name="IsMessengerEnabled" type="xs:boolean" minOccurs="0" />
+ <xs:element name="Capabilities" type="xs:long" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EmailAddressDictionaryEntryType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Key" type="t:EmailAddressKeyType" use="required" />
+ <xs:attribute name="Name" type="xs:string" use="optional" />
+ <xs:attribute name="RoutingType" type="xs:string" use="optional" />
+ <xs:attribute name="MailboxType" type="t:MailboxTypeType" use="optional" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="PhoneNumberDictionaryEntryType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Key" type="t:PhoneNumberKeyType" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="PhysicalAddressDictionaryEntryType">
+ <xs:sequence>
+ <xs:element name="Street" type="xs:string" minOccurs="0" />
+ <xs:element name="City" type="xs:string" minOccurs="0" />
+ <xs:element name="State" type="xs:string" minOccurs="0" />
+ <xs:element name="CountryOrRegion" type="xs:string" minOccurs="0" />
+ <xs:element name="PostalCode" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="Key" type="t:PhysicalAddressKeyType" use="required" />
+ </xs:complexType>
+
+ <!-- The actual dictionaries -->
+
+ <xs:complexType name="ContactUrlDictionaryType">
+ <xs:sequence>
+ <xs:element name="Url" type="t:ContactUrlDictionaryEntryType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AbchEmailAddressDictionaryType">
+ <xs:sequence>
+ <xs:element name="Email" type="t:AbchEmailAddressDictionaryEntryType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ImAddressDictionaryType">
+ <xs:sequence>
+ <xs:element name="Entry" type="t:ImAddressDictionaryEntryType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EmailAddressDictionaryType">
+ <xs:sequence>
+ <xs:element name="Entry" type="t:EmailAddressDictionaryEntryType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PhoneNumberDictionaryType">
+ <xs:sequence>
+ <xs:element name="Entry" type="t:PhoneNumberDictionaryEntryType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PhysicalAddressDictionaryType">
+ <xs:sequence>
+ <xs:element name="Entry" type="t:PhysicalAddressDictionaryEntryType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="MemberStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Unrecognized" />
+ <xs:enumeration value="Normal" />
+ <xs:enumeration value="Demoted" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="MembersListType">
+ <xs:sequence>
+ <xs:element name="Member" type="t:MemberType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MemberType">
+ <xs:sequence>
+ <xs:element name="Mailbox" type="t:EmailAddressType" minOccurs="0" />
+ <xs:element name="Status" type="t:MemberStatusType" minOccurs="0" />
+ </xs:sequence>
+ <xs:attribute name="Key" type="xs:string" use="optional" />
+ </xs:complexType>
+
+ <xs:complexType name="RoleMemberItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" />
+ <xs:element name="Type" type="t:RoleMemberTypeType" minOccurs="0" />
+ <xs:element name="MemberId" type="xs:string" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NetworkItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="DomainId" type="xs:int" minOccurs="0" />
+ <xs:element name="DomainTag" type="xs:string" minOccurs="0" />
+ <xs:element name="UserTileUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="ProfileUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="Settings" type="xs:int" minOccurs="0" />
+ <xs:element name="IsDefault" type="xs:boolean" minOccurs="0" />
+ <xs:element name="AutoLinkError" type="xs:string" minOccurs="0" />
+ <xs:element name="AutoLinkSuccess" type="xs:string" minOccurs="0" />
+ <xs:element name="UserEmail" type="xs:string" minOccurs="0" />
+ <xs:element name="ClientPublishSecret" type="xs:string" minOccurs="0" />
+ <xs:element name="ClientToken" type="xs:string" minOccurs="0" />
+ <xs:element name="ClientToken2" type="xs:string" minOccurs="0" />
+ <xs:element name="ContactSyncError" type="xs:string" minOccurs="0" />
+ <xs:element name="ContactSyncSuccess" type="xs:string" minOccurs="0" />
+ <xs:element name="ErrorOffers" type="xs:int" minOccurs="0" />
+ <xs:element name="FirstAuthErrorDates" type="xs:string" minOccurs="0" />
+ <xs:element name="LastVersionSaved" type="xs:int" minOccurs="0" />
+ <xs:element name="LastWelcomeContact" type="xs:string" minOccurs="0" />
+ <xs:element name="Offers" type="xs:int" minOccurs="0" />
+ <xs:element name="PsaLastChanged" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="RefreshToken2" type="xs:string" minOccurs="0" />
+ <xs:element name="RefreshTokenExpiry2" type="xs:string" minOccurs="0" />
+ <xs:element name="SessionHandle" type="xs:string" minOccurs="0" />
+ <xs:element name="RejectedOffers" type="xs:int" minOccurs="0" />
+ <xs:element name="SyncEnabled" type="xs:boolean" minOccurs="0" />
+ <xs:element name="TokenRefreshLastAttempted" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="TokenRefreshLastCompleted" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="PsaState" type="xs:string" minOccurs="0" />
+ <xs:element name="SourceEntryID" type="xs:base64Binary" minOccurs="0" />
+ <xs:element name="AccountName" type="xs:string" minOccurs="0" />
+ <xs:element name="LastSync" type="xs:dateTime" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AbchPersonItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="AntiLinkInfo" type="xs:string" minOccurs="0" />
+ <xs:element name="PersonId" type="t:GuidType" minOccurs="0" />
+ <xs:element name="ContactHandles" type="t:ArrayOfAbchPersonContactHandlesType" minOccurs="0" />
+ <xs:element name="ContactCategories" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="RelevanceOrder1" type="xs:string" minOccurs="0" />
+ <xs:element name="RelevanceOrder2" type="xs:string" minOccurs="0" />
+ <xs:element name="TrustLevel" type="xs:int" minOccurs="0" />
+ <xs:element name="FavoriteOrder" type="xs:int" minOccurs="0" />
+ <xs:element name="ExchangePersonIdGuid" type="t:GuidType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfAbchPersonContactHandlesType">
+ <xs:sequence>
+ <xs:element name="ContactHandle" type="t:AbchPersonContactHandle" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AbchPersonContactHandle">
+ <xs:sequence>
+ <xs:element name="SourceId" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ObjectId" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="AccountName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfGuidType">
+ <xs:sequence>
+ <xs:element name="Guid" type="t:GuidType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- ContactItemType -->
+
+ <xs:complexType name="ContactItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="FileAs" type="xs:string" minOccurs="0" />
+ <xs:element name="FileAsMapping" type="t:FileAsMappingType" minOccurs="0" />
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" />
+ <xs:element name="GivenName" type="xs:string" minOccurs="0" />
+ <xs:element name="Initials" type="xs:string" minOccurs="0" />
+ <xs:element name="MiddleName" type="xs:string" minOccurs="0" />
+ <xs:element name="Nickname" type="xs:string" minOccurs="0" />
+ <xs:element name="CompleteName" type="t:CompleteNameType" minOccurs="0" />
+ <xs:element name="CompanyName" type="xs:string" minOccurs="0" />
+ <xs:element name="EmailAddresses" type="t:EmailAddressDictionaryType" minOccurs="0" />
+ <xs:element name="AbchEmailAddresses" type="t:AbchEmailAddressDictionaryType" minOccurs="0" />
+ <xs:element name="PhysicalAddresses" type="t:PhysicalAddressDictionaryType" minOccurs="0" />
+ <xs:element name="PhoneNumbers" type="t:PhoneNumberDictionaryType" minOccurs="0" />
+ <xs:element name="AssistantName" type="xs:string" minOccurs="0" />
+ <xs:element name="Birthday" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="BusinessHomePage" type="xs:anyURI" minOccurs="0" />
+ <xs:element name="Children" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="Companies" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="ContactSource" type="t:ContactSourceType" minOccurs="0" />
+ <xs:element name="Department" type="xs:string" minOccurs="0" />
+ <xs:element name="Generation" type="xs:string" minOccurs="0" />
+ <xs:element name="ImAddresses" type="t:ImAddressDictionaryType" minOccurs="0" />
+ <xs:element name="JobTitle" type="xs:string" minOccurs="0" />
+ <xs:element name="Manager" type="xs:string" minOccurs="0" />
+ <xs:element name="Mileage" type="xs:string" minOccurs="0" />
+ <xs:element name="OfficeLocation" type="xs:string" minOccurs="0" />
+ <xs:element name="PostalAddressIndex" type="t:PhysicalAddressIndexType" minOccurs="0" />
+ <xs:element name="Profession" type="xs:string" minOccurs="0" />
+ <xs:element name="SpouseName" type="xs:string" minOccurs="0" />
+ <xs:element name="Surname" type="xs:string" minOccurs="0" />
+ <xs:element name="WeddingAnniversary" type="xs:dateTime" minOccurs="0" />
+ <xs:element name="HasPicture" type="xs:boolean" minOccurs="0" />
+ <xs:element name="PhoneticFullName" type="xs:string" minOccurs="0" />
+ <xs:element name="PhoneticFirstName" type="xs:string" minOccurs="0" />
+ <xs:element name="PhoneticLastName" type="xs:string" minOccurs="0" />
+ <xs:element name="Alias" type="xs:string" minOccurs="0" />
+ <xs:element name="Notes" type="xs:string" minOccurs="0" />
+ <xs:element name="Photo" type="xs:base64Binary" minOccurs="0" />
+ <xs:element name="UserSMIMECertificate" type="t:ArrayOfBinaryType" minOccurs="0" />
+ <xs:element name="MSExchangeCertificate" type="t:ArrayOfBinaryType" minOccurs="0" />
+ <xs:element name="DirectoryId" type="xs:string" minOccurs="0" />
+ <xs:element name="ManagerMailbox" type="t:SingleRecipientType" minOccurs="0" />
+ <xs:element name="DirectReports" type="t:ArrayOfRecipientsType" minOccurs="0" />
+ <xs:element name="AccountName" type="xs:string" minOccurs="0" />
+ <xs:element name="IsAutoUpdateDisabled" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsMessengerEnabled" type="xs:boolean" minOccurs="0" />
+ <xs:element name="Comment" type="xs:string" minOccurs="0" />
+ <xs:element name="ContactShortId" type="xs:int" minOccurs="0" />
+ <xs:element name="ContactType" type="xs:string" minOccurs="0" />
+ <xs:element name="Gender" type="xs:string" minOccurs="0" />
+ <xs:element name="IsHidden" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ObjectId" type="xs:string" minOccurs="0" />
+ <xs:element name="PassportId" type="xs:long" minOccurs="0" />
+ <xs:element name="IsPrivate" type="xs:boolean" minOccurs="0" />
+ <xs:element name="SourceId" type="xs:string" minOccurs="0" />
+ <xs:element name="TrustLevel" type="xs:int" minOccurs="0" />
+ <xs:element name="CreatedBy" type="xs:string" minOccurs="0" />
+ <xs:element name="Urls" type="t:ContactUrlDictionaryType" minOccurs="0" />
+ <xs:element name="Cid" type="xs:long" minOccurs="0" />
+ <xs:element name="SkypeAuthCertificate" type="xs:string" minOccurs="0" />
+ <xs:element name="SkypeContext" type="xs:string" minOccurs="0" />
+ <xs:element name="SkypeId" type="xs:string" minOccurs="0" />
+ <xs:element name="SkypeRelationship" type="xs:string" minOccurs="0" />
+ <xs:element name="YomiNickname" type="xs:string" minOccurs="0" />
+ <xs:element name="XboxLiveTag" type="xs:string" minOccurs="0" />
+ <xs:element name="InviteFree" type="xs:boolean" minOccurs="0" />
+ <xs:element name="HidePresenceAndProfile" type="xs:boolean" minOccurs="0" />
+ <xs:element name="IsPendingOutbound" type="xs:boolean" minOccurs="0" />
+ <xs:element name="SupportGroupFeeds" type="xs:boolean" minOccurs="0" />
+ <xs:element name="UserTileHash" type="xs:string" minOccurs="0" />
+ <xs:element name="UnifiedInbox" type="xs:boolean" minOccurs="0" />
+ <xs:element name="Mris" type="t:ArrayOfStringsType" minOccurs="0" />
+ <xs:element name="Wlid" type="xs:string" minOccurs="0" />
+ <xs:element name="AbchContactId" type="t:GuidType" minOccurs="0" />
+ <xs:element name="NotInBirthdayCalendar" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ShellContactType" type="xs:string" minOccurs="0" />
+ <xs:element name="ImMri" type="xs:string" minOccurs="0" />
+ <xs:element name="PresenceTrustLevel" type="xs:int" minOccurs="0" />
+ <xs:element name="OtherMri" type="xs:string" minOccurs="0" />
+ <xs:element name="ProfileLastChanged" type="xs:string" minOccurs="0" />
+ <xs:element name="MobileIMEnabled" type="xs:boolean" minOccurs="0" />
+ <xs:element name="PartnerNetworkProfilePhotoUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="PartnerNetworkThumbnailPhotoUrl" type="xs:string" minOccurs="0" />
+ <xs:element name="PersonId" type="xs:string" minOccurs="0" />
+ <xs:element name="ConversationGuid" type="t:GuidType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfBinaryType">
+ <xs:sequence>
+ <xs:element name="Base64Binary" type="xs:base64Binary" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- ContactItemType -->
+
+ <xs:complexType name="DistributionListType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:sequence>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" />
+ <xs:element name="FileAs" type="xs:string" minOccurs="0" />
+ <xs:element name="ContactSource" type="t:ContactSourceType" minOccurs="0" />
+
+ <xs:element name="Members" type="t:MembersListType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- End of Contacts Types-->
+
+ <!-- Description of a search folder -->
+
+ <xs:complexType name="SearchParametersType">
+ <xs:sequence>
+ <xs:element name="Restriction" type="t:RestrictionType" />
+ <xs:element name="BaseFolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType" />
+ </xs:sequence>
+ <xs:attribute name="Traversal" type="t:SearchFolderTraversalType" use="optional"/>
+ </xs:complexType>
+
+ <!-- Search expressions -->
+ <xs:complexType name="ConstantValueType">
+ <xs:attribute name="Value" type="xs:string" use="required" />
+ </xs:complexType>
+
+ <!-- Search expression type -->
+ <xs:complexType name="SearchExpressionType" abstract="true" />
+ <xs:element name="SearchExpression" type="t:SearchExpressionType" />
+
+ <!-- GroupBy types for FindItem -->
+ <xs:simpleType name="AggregateType">
+ <xs:annotation>
+ <xs:documentation>
+ This max/min evaluation is applied to the field specified within the group by
+ instance for EACH item within that group. This determines which item from each group
+ is to be selected as the representative for that group.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Minimum"/>
+ <xs:enumeration value="Maximum"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="AggregateOnType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents the field of each item to aggregate on and the qualifier to apply to that
+ field in determining which item will represent the group.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:choice>
+ <!-- Note that the property path here determines which property to examine on each item
+ in the group for the aggregation function. This has nothing to do with definition what
+ is in each group. That determination has already been made via the GroupBy property path.
+ -->
+ <xs:element name="FieldURI" type="t:PathToUnindexedFieldType"/>
+ <xs:element name="IndexedFieldURI" type="t:PathToIndexedFieldType"/>
+ <xs:element name="ExtendedFieldURI" type="t:PathToExtendedFieldType"/>
+ </xs:choice>
+ <xs:attribute name="Aggregate" type="t:AggregateType" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="BaseGroupByType" abstract ="true">
+ <xs:attribute name="Order" type="t:SortDirectionType" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="GroupByType">
+ <xs:annotation>
+ <xs:documentation>
+ Allows consumers to specify arbitrary groupings for FindItem queries.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BaseGroupByType">
+ <xs:sequence>
+ <!-- This property path represents the property that defines what is in each group.
+ All items within a given group will have the same value for this property. -->
+ <xs:choice>
+ <xs:element name="FieldURI" type="t:PathToUnindexedFieldType"/>
+ <xs:element name="IndexedFieldURI" type="t:PathToIndexedFieldType"/>
+ <xs:element name="ExtendedFieldURI" type="t:PathToExtendedFieldType"/>
+ </xs:choice>
+ <xs:element name="AggregateOn" type="t:AggregateOnType"/>
+ <xs:element name="UseCollapsibleGroups" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="ItemsPerGroup" type="xs:nonNegativeInteger" minOccurs="0" />
+ <xs:element name="MaxItemsPerGroup" type="xs:nonNegativeInteger" minOccurs="0" />
+ <xs:element name="GroupsToExpand" type="t:ArrayOfGroupIdType" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="StandardGroupByType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents standard groupings for GroupBy queries.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ConversationTopic"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="DistinguishedGroupByType">
+ <xs:annotation>
+ <xs:documentation>
+ Allows consumers to access standard groupings for FindItem queries. This is in
+ contrast to the arbitrary (custom) groupings available via the t:GroupByType
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BaseGroupByType">
+ <xs:sequence>
+ <xs:element name="StandardGroupBy" type="t:StandardGroupByType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfGroupIdType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="GroupId" type="xs:base64Binary"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- GroupBy result types -->
+
+ <xs:complexType name="GroupedItemsType">
+ <xs:sequence>
+ <xs:element name="GroupIndex" type="xs:string"/>
+ <xs:element name="Items" type="t:ArrayOfRealItemsType"/>
+ <xs:element name="GroupSummary" type="t:GroupSummaryType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfGroupedItemsType">
+ <xs:choice>
+ <xs:element name="GroupedItems" type="t:GroupedItemsType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="GroupSummaryType">
+ <xs:sequence>
+ <xs:element name="GroupCount" type="xs:int" />
+ <xs:element name="UnreadCount" type="xs:int" />
+ <xs:element name="InstanceKey" type="xs:base64Binary" />
+ <xs:element name="GroupByValue" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Basic arithmetic operations -->
+
+ <xs:complexType name="ExistsType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchExpressionType">
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Exists" type="t:ExistsType" substitutionGroup="t:SearchExpression"/>
+
+ <xs:complexType name="FieldURIOrConstantType">
+ <xs:choice>
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ <xs:element name="Constant" type="t:ConstantValueType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="TwoOperandExpressionType" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="t:SearchExpressionType">
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ </xs:choice>
+ <xs:element name="FieldURIOrConstant" type="t:FieldURIOrConstantType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Excludes patterns can either be hex (starting with 0x or 0X) or integers -->
+ <xs:simpleType name="ExcludesAttributeType">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="((0x|0X)[0-9A-Fa-f]*)|([0-9]*)"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ExcludesValueType">
+ <xs:attribute name="Value" type="t:ExcludesAttributeType" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="ExcludesType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchExpressionType">
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ </xs:choice>
+ <xs:element name="Bitmask" type="t:ExcludesValueType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Excludes" type="t:ExcludesType" substitutionGroup ="t:SearchExpression"/>
+
+
+ <xs:complexType name="IsEqualToType">
+ <xs:complexContent>
+ <xs:extension base="t:TwoOperandExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="IsEqualTo" type="t:IsEqualToType" substitutionGroup ="t:SearchExpression"/>
+ <xs:complexType name="IsNotEqualToType">
+ <xs:complexContent>
+ <xs:extension base="t:TwoOperandExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="IsNotEqualTo" type="t:IsNotEqualToType" substitutionGroup="t:SearchExpression"/>
+ <xs:complexType name="IsGreaterThanType">
+ <xs:complexContent>
+ <xs:extension base="t:TwoOperandExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="IsGreaterThan" type="t:IsGreaterThanType" substitutionGroup ="t:SearchExpression"/>
+ <xs:complexType name="IsGreaterThanOrEqualToType">
+ <xs:complexContent>
+ <xs:extension base="t:TwoOperandExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="IsGreaterThanOrEqualTo" type="t:IsGreaterThanOrEqualToType" substitutionGroup ="t:SearchExpression"/>
+ <xs:complexType name="IsLessThanType">
+ <xs:complexContent>
+ <xs:extension base="t:TwoOperandExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="IsLessThan" type="t:IsLessThanType" substitutionGroup ="t:SearchExpression"/>
+ <xs:complexType name="IsLessThanOrEqualToType">
+ <xs:complexContent>
+ <xs:extension base="t:TwoOperandExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="IsLessThanOrEqualTo" type="t:IsLessThanOrEqualToType" substitutionGroup ="t:SearchExpression"/>
+
+
+ <!-- Content indexing comparison -->
+ <xs:simpleType name="ContainmentModeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="FullString" />
+ <xs:enumeration value="Prefixed" />
+ <xs:enumeration value="Substring" />
+ <xs:enumeration value="PrefixOnWords" />
+ <xs:enumeration value="ExactPhrase" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="ContainmentComparisonType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Exact" />
+ <xs:enumeration value="IgnoreCase" />
+ <xs:enumeration value="IgnoreNonSpacingCharacters" />
+ <xs:enumeration value="Loose"/>
+ <xs:enumeration value="IgnoreCaseAndNonSpacingCharacters" />
+ <xs:enumeration value="LooseAndIgnoreCase"/>
+ <xs:enumeration value="LooseAndIgnoreNonSpace"/>
+ <xs:enumeration value="LooseAndIgnoreCaseAndIgnoreNonSpace"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ContainsExpressionType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchExpressionType">
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ </xs:choice>
+ <xs:element name="Constant" type="t:ConstantValueType" />
+ </xs:sequence>
+ <xs:attribute name="ContainmentMode" type="t:ContainmentModeType" use="optional" />
+ <xs:attribute name="ContainmentComparison" type="t:ContainmentComparisonType" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Contains" type="t:ContainsExpressionType" substitutionGroup="t:SearchExpression"/>
+
+ <!-- Boolean operations -->
+ <xs:complexType name="NotType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchExpressionType">
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:Contains"/>
+ <xs:element ref="t:Excludes"/>
+ <xs:element ref="t:Exists"/>
+ <xs:element ref="t:IsEqualTo"/>
+ <xs:element ref="t:IsNotEqualTo"/>
+ <xs:element ref="t:IsGreaterThan"/>
+ <xs:element ref="t:IsGreaterThanOrEqualTo"/>
+ <xs:element ref="t:IsLessThan"/>
+ <xs:element ref="t:IsLessThanOrEqualTo"/>
+ <xs:element ref="t:And"/>
+ <xs:element ref="t:Not"/>
+ <xs:element ref="t:Or"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Not" type="t:NotType" substitutionGroup="t:SearchExpression"/>
+
+ <xs:complexType name="MultipleOperandBooleanExpressionType" abstract="true">
+ <xs:complexContent>
+ <xs:extension base="t:SearchExpressionType">
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:Contains"/>
+ <xs:element ref="t:Excludes"/>
+ <xs:element ref="t:Exists"/>
+ <xs:element ref="t:IsEqualTo"/>
+ <xs:element ref="t:IsNotEqualTo"/>
+ <xs:element ref="t:IsGreaterThan"/>
+ <xs:element ref="t:IsGreaterThanOrEqualTo"/>
+ <xs:element ref="t:IsLessThan"/>
+ <xs:element ref="t:IsLessThanOrEqualTo"/>
+ <xs:element ref="t:And"/>
+ <xs:element ref="t:Not"/>
+ <xs:element ref="t:Or"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AndType">
+ <xs:complexContent>
+ <xs:extension base="t:MultipleOperandBooleanExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="And" type="t:AndType" substitutionGroup="t:SearchExpression"/>
+
+ <xs:complexType name="OrType">
+ <xs:complexContent>
+ <xs:extension base="t:MultipleOperandBooleanExpressionType"/>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Or" type="t:OrType" substitutionGroup="t:SearchExpression"/>
+
+ <xs:complexType name="NearType">
+ <xs:complexContent>
+ <xs:extension base="t:MultipleOperandBooleanExpressionType">
+ <xs:sequence>
+ <xs:element name="Distance" type="xs:unsignedInt" />
+ <xs:element name="Ordered" type="xs:boolean" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:element name="Near" type="t:NearType" substitutionGroup="t:SearchExpression"/>
+
+ <!-- The type of object which actually encodes a restriction -->
+ <xs:complexType name="RestrictionType">
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:Contains"/>
+ <xs:element ref="t:Excludes"/>
+ <xs:element ref="t:Exists"/>
+ <xs:element ref="t:IsEqualTo"/>
+ <xs:element ref="t:IsNotEqualTo"/>
+ <xs:element ref="t:IsGreaterThan"/>
+ <xs:element ref="t:IsGreaterThanOrEqualTo"/>
+ <xs:element ref="t:IsLessThan"/>
+ <xs:element ref="t:IsLessThanOrEqualTo"/>
+ <xs:element ref="t:And"/>
+ <xs:element ref="t:Not"/>
+ <xs:element ref="t:Or"/>
+ </xs:choice>
+ </xs:complexType>
+ <!-- Sort order specification -->
+ <xs:simpleType name="SortDirectionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Ascending" />
+ <xs:enumeration value="Descending" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="FieldOrderType">
+ <xs:sequence>
+ <xs:choice maxOccurs ="unbounded">
+ <xs:element ref="t:FieldURI"/>
+ <xs:element ref="t:IndexedFieldURI"/>
+ <xs:element ref="t:ExtendedFieldURI"/>
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute name="Order" type="t:SortDirectionType" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfFieldOrdersType">
+ <xs:sequence>
+ <xs:element name="FieldOrder" type="t:FieldOrderType" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Data type needed by CreateManagedFolder. -->
+ <xs:complexType name="NonEmptyArrayOfFolderNamesType">
+ <xs:sequence>
+ <xs:element name="FolderName" type="xs:string" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Notification types -->
+
+ <xs:simpleType name="WatermarkType">
+ <xs:restriction base="t:NonEmptyStringType"/>
+ </xs:simpleType>
+
+ <xs:simpleType name="SubscriptionIdType">
+ <xs:restriction base="t:NonEmptyStringType"/>
+ </xs:simpleType>
+
+ <xs:complexType name="BaseNotificationEventType">
+ <xs:sequence>
+ <xs:element name="Watermark" type="t:WatermarkType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="BaseObjectChangedEventType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseNotificationEventType">
+ <xs:sequence>
+ <xs:element name="TimeStamp" type="xs:dateTime" />
+ <xs:choice>
+ <xs:element name="FolderId" type="t:FolderIdType" />
+ <xs:element name="ItemId" type="t:ItemIdType"/>
+ </xs:choice>
+ <xs:element name="ParentFolderId" type="t:FolderIdType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ModifiedEventType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseObjectChangedEventType">
+ <xs:sequence>
+ <xs:element name="UnreadCount" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MovedCopiedEventType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseObjectChangedEventType">
+ <xs:sequence>
+ <xs:choice>
+ <xs:element name="OldFolderId" type="t:FolderIdType" />
+ <xs:element name="OldItemId" type="t:ItemIdType"/>
+ </xs:choice>
+ <xs:element name="OldParentFolderId" type="t:FolderIdType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NotificationType">
+ <xs:sequence>
+ <xs:element name="SubscriptionId" type="t:SubscriptionIdType" />
+ <xs:element name="PreviousWatermark" type="t:WatermarkType" minOccurs="0" />
+ <xs:element name="MoreEvents" type="xs:boolean" minOccurs="0" />
+ <xs:choice maxOccurs="unbounded" minOccurs="1">
+ <xs:element name="CopiedEvent" type="t:MovedCopiedEventType"/>
+ <xs:element name="CreatedEvent" type="t:BaseObjectChangedEventType"/>
+ <xs:element name="DeletedEvent" type="t:BaseObjectChangedEventType"/>
+ <xs:element name="ModifiedEvent" type="t:ModifiedEventType"/>
+ <xs:element name="MovedEvent" type="t:MovedCopiedEventType"/>
+ <xs:element name="NewMailEvent" type="t:BaseObjectChangedEventType"/>
+ <xs:element name="StatusEvent" type="t:BaseNotificationEventType"/>
+ <xs:element name="FreeBusyChangedEvent" type="t:BaseObjectChangedEventType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="NotificationEventTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="CopiedEvent" />
+ <xs:enumeration value="CreatedEvent" />
+ <xs:enumeration value="DeletedEvent" />
+ <xs:enumeration value="ModifiedEvent" />
+ <xs:enumeration value="MovedEvent" />
+ <xs:enumeration value="NewMailEvent" />
+ <xs:enumeration value="FreeBusyChangedEvent" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NonEmptyArrayOfNotificationEventTypesType">
+ <xs:choice maxOccurs="unbounded" minOccurs="1">
+ <xs:element name="EventType" type="t:NotificationEventTypeType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:simpleType name="SubscriptionTimeoutType">
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="1" />
+ <xs:maxInclusive value="1440" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="SubscriptionStatusFrequencyType">
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="1" />
+ <xs:maxInclusive value="1440" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="BaseSubscriptionRequestType" abstract="true">
+ <xs:sequence>
+ <xs:element name="FolderIds" type="t:NonEmptyArrayOfBaseFolderIdsType" minOccurs="0"/>
+ <xs:element name="EventTypes" type="t:NonEmptyArrayOfNotificationEventTypesType"/>
+ <xs:element name="Watermark" type="t:WatermarkType" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="SubscribeToAllFolders" type="xs:boolean" use="optional"/>
+ </xs:complexType>
+ <xs:complexType name="PushSubscriptionRequestType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseSubscriptionRequestType">
+ <xs:sequence>
+ <xs:element name="StatusFrequency" type="t:SubscriptionStatusFrequencyType"/>
+ <xs:element name="URL" type="xs:string"/>
+ <xs:element name="CallerData" type="xs:string" minOccurs ="0" maxOccurs ="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="PullSubscriptionRequestType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseSubscriptionRequestType">
+ <xs:sequence>
+ <xs:element name="Timeout" type="t:SubscriptionTimeoutType"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="StreamingSubscriptionRequestType">
+ <xs:sequence>
+ <xs:element name="FolderIds"
+ type="t:NonEmptyArrayOfBaseFolderIdsType" minOccurs="0"/>
+ <xs:element name="EventTypes" type="t:NonEmptyArrayOfNotificationEventTypesType"/>
+ </xs:sequence>
+ <xs:attribute name="SubscribeToAllFolders" type="xs:boolean" use="optional"/>
+ </xs:complexType>
+
+ <xs:simpleType name="SubscriptionStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="OK" />
+ <xs:enumeration value="Unsubscribe" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NonEmptyArrayOfSubscriptionIdsType">
+ <xs:sequence>
+ <xs:element name="SubscriptionId" type="t:SubscriptionIdType" minOccurs="1"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfNotificationsType">
+ <xs:sequence>
+ <xs:element name="Notification" type="t:NotificationType" minOccurs="0"
+ maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="StreamingSubscriptionConnectionTimeoutType">
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="1" />
+ <xs:maxInclusive value="30" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ConnectionStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="OK" />
+ <xs:enumeration value="Closed" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="UnifiedGroupAccessType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Private" />
+ <xs:enumeration value="Secret" />
+ <xs:enumeration value="Public" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="SyncFolderItemsDeleteType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SyncFolderItemsReadFlagType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType"/>
+ <xs:element name="IsRead" type="xs:boolean"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SyncFolderItemsChangesType">
+ <xs:sequence>
+ <xs:choice maxOccurs="unbounded" minOccurs="0">
+ <xs:element name="Create" type="t:SyncFolderItemsCreateOrUpdateType"/>
+ <xs:element name="Update" type="t:SyncFolderItemsCreateOrUpdateType"/>
+ <xs:element name="Delete" type="t:SyncFolderItemsDeleteType"/>
+ <xs:element name="ReadFlagChange" type="t:SyncFolderItemsReadFlagType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <xs:complexType name="SyncFolderHierarchyCreateOrUpdateType">
+ <xs:choice>
+ <xs:element name="Folder" type="t:FolderType"/>
+ <xs:element name="CalendarFolder" type="t:CalendarFolderType"/>
+ <xs:element name="ContactsFolder" type="t:ContactsFolderType"/>
+ <xs:element name="SearchFolder" type="t:SearchFolderType"/>
+ <xs:element name="TasksFolder" type="t:TasksFolderType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="SyncFolderHierarchyDeleteType">
+ <xs:sequence>
+ <xs:element name="FolderId" type="t:FolderIdType"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SyncFolderHierarchyChangesType">
+ <xs:sequence>
+ <xs:choice maxOccurs="unbounded" minOccurs="0">
+ <xs:element name="Create" type="t:SyncFolderHierarchyCreateOrUpdateType"/>
+ <xs:element name="Update" type="t:SyncFolderHierarchyCreateOrUpdateType"/>
+ <xs:element name="Delete" type="t:SyncFolderHierarchyDeleteType"/>
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="MaxSyncChangesReturnedType">
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="1" />
+ <xs:maxInclusive value="512" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="SyncFolderItemsScopeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NormalItems" />
+ <xs:enumeration value="NormalAndAssociatedItems" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Availability Service types -->
+
+ <xs:simpleType name="AvailabilityProxyRequestType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="CrossSite" />
+ <xs:enumeration value="CrossForest" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="RequestTypeHeader">
+ <xs:sequence>
+ <xs:element name="RequestType" type="t:AvailabilityProxyRequestType" minOccurs ="1" maxOccurs ="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="MeetingAttendeeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Organizer"/>
+ <xs:enumeration value="Required"/>
+ <xs:enumeration value="Optional"/>
+ <xs:enumeration value="Room"/>
+ <xs:enumeration value="Resource"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="CalendarEventDetails">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="ID" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Subject" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Location" type="xs:string" />
+ <xs:element minOccurs="1" maxOccurs="1" name="IsMeeting" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="IsRecurring" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="IsException" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="IsReminderSet" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="IsPrivate" type="xs:boolean" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="CalendarEvent">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="StartTime" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="EndTime" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="BusyType" type="t:LegacyFreeBusyType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="CalendarEventDetails" type="t:CalendarEventDetails" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfCalendarEvent">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="CalendarEvent" type="t:CalendarEvent" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Duration">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="StartTime" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="EndTime" type="xs:dateTime" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EmailAddress">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
+ <xs:element minOccurs="1" maxOccurs="1" name="Address" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="RoutingType" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="Mailbox" type="t:EmailAddress" />
+
+ <xs:simpleType name="FreeBusyViewType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="MergedOnly" />
+ <xs:enumeration value="FreeBusy" />
+ <xs:enumeration value="FreeBusyMerged" />
+ <xs:enumeration value="Detailed" />
+ <xs:enumeration value="DetailedMerged" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:complexType name="FreeBusyViewOptionsType">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="TimeWindow" type="t:Duration" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MergedFreeBusyIntervalInMinutes" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="RequestedView" type="t:FreeBusyViewType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="FreeBusyViewOptions" type="t:FreeBusyViewOptionsType" />
+
+ <xs:complexType name="WorkingPeriod">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="DayOfWeek" type="t:DaysOfWeekType" />
+ <xs:element minOccurs="1" maxOccurs="1" name="StartTimeInMinutes" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="EndTimeInMinutes" type="xs:int" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfWorkingPeriod">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="WorkingPeriod" type="t:WorkingPeriod" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SerializableTimeZoneTime">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="Bias" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="Time" type="xs:string" />
+ <xs:element minOccurs="1" maxOccurs="1" name="DayOrder" type="xs:short" />
+ <xs:element minOccurs="1" maxOccurs="1" name="Month" type="xs:short" />
+ <xs:element minOccurs="1" maxOccurs="1" name="DayOfWeek" type="t:DayOfWeekType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Year" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SerializableTimeZone">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="Bias" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="StandardTime" type="t:SerializableTimeZoneTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="DaylightTime" type="t:SerializableTimeZoneTime" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="TimeZone" type="t:SerializableTimeZone" />
+
+ <xs:complexType name="WorkingHours">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="TimeZone" type="t:SerializableTimeZone" />
+ <xs:element minOccurs="1" maxOccurs="1" name="WorkingPeriodArray" type="t:ArrayOfWorkingPeriod" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FreeBusyView">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="FreeBusyViewType" type="t:FreeBusyViewType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MergedFreeBusy" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="CalendarEventArray" type="t:ArrayOfCalendarEvent" />
+ <xs:element minOccurs="0" maxOccurs="1" name="WorkingHours" type="t:WorkingHours" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxData">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="Email" type="t:EmailAddress" />
+ <xs:element minOccurs="1" maxOccurs="1" name="AttendeeType" type="t:MeetingAttendeeType" />
+ <xs:element minOccurs="0" maxOccurs="1" name="ExcludeConflicts" type="xs:boolean" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfMailboxData">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="MailboxData" nillable="true" type="t:MailboxData" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="SuggestionQuality">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Excellent" />
+ <xs:enumeration value="Good" />
+ <xs:enumeration value="Fair" />
+ <xs:enumeration value="Poor" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="SuggestionsViewOptionsType">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="GoodThreshold" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MaximumResultsByDay" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MaximumNonWorkHourResultsByDay" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MeetingDurationInMinutes" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MinimumSuggestionQuality" type="t:SuggestionQuality" />
+ <xs:element minOccurs="1" maxOccurs="1" name="DetailedSuggestionsWindow" type="t:Duration" />
+ <xs:element minOccurs="0" maxOccurs="1" name="CurrentMeetingTime" type="xs:dateTime" />
+ <xs:element minOccurs="0" maxOccurs="1" name="GlobalObjectId" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="SuggestionsViewOptions" type="t:SuggestionsViewOptionsType" />
+
+ <xs:complexType name="ArrayOfAttendeeConflictData">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element minOccurs="1" maxOccurs="1" name="UnknownAttendeeConflictData" nillable="true" type="t:UnknownAttendeeConflictData" />
+ <xs:element minOccurs="1" maxOccurs="1" name="IndividualAttendeeConflictData" nillable="true" type="t:IndividualAttendeeConflictData" />
+ <xs:element minOccurs="1" maxOccurs="1" name="TooBigGroupAttendeeConflictData" nillable="true" type="t:TooBigGroupAttendeeConflictData" />
+ <xs:element minOccurs="1" maxOccurs="1" name="GroupAttendeeConflictData" nillable="true" type="t:GroupAttendeeConflictData" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="AttendeeConflictData" abstract="true"/>
+
+ <xs:complexType name="UnknownAttendeeConflictData">
+ <xs:complexContent mixed="false">
+ <xs:extension base="t:AttendeeConflictData" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="TooBigGroupAttendeeConflictData">
+ <xs:complexContent mixed="false">
+ <xs:extension base="t:AttendeeConflictData" />
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="IndividualAttendeeConflictData">
+ <xs:complexContent mixed="false">
+ <xs:extension base="t:AttendeeConflictData">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="BusyType" type="t:LegacyFreeBusyType" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="GroupAttendeeConflictData">
+ <xs:complexContent mixed="false">
+ <xs:extension base="t:AttendeeConflictData">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="NumberOfMembers" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="NumberOfMembersAvailable" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="NumberOfMembersWithConflict" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="NumberOfMembersWithNoData" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="Suggestion">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="MeetingTime" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="IsWorkTime" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="SuggestionQuality" type="t:SuggestionQuality" />
+ <xs:element minOccurs="0" maxOccurs="1" name="AttendeeConflictDataArray" type="t:ArrayOfAttendeeConflictData" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSuggestion">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="Suggestion" type="t:Suggestion" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SuggestionDayResult">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="Date" type="xs:dateTime" />
+ <xs:element minOccurs="1" maxOccurs="1" name="DayQuality" type="t:SuggestionQuality" />
+ <xs:element minOccurs="0" maxOccurs="1" name="SuggestionArray" type="t:ArrayOfSuggestion" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSuggestionDayResult">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="SuggestionDayResult" type="t:SuggestionDayResult" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="OofState">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Disabled" />
+ <xs:enumeration value="Enabled" />
+ <xs:enumeration value="Scheduled" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ExternalAudience">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Known" />
+ <xs:enumeration value="All" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ReplyBody">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" name="Message" type="xs:string" />
+ </xs:sequence>
+ <xs:attribute ref="xml:lang" use="optional" />
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfEventIDType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="EventToDeleteID" type="xs:string" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="UserOofSettings">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="OofState" type="t:OofState" />
+ <xs:element minOccurs="1" maxOccurs="1" name="ExternalAudience" type="t:ExternalAudience" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Duration" type="t:Duration" />
+ <xs:element minOccurs="0" maxOccurs="1" name="InternalReply" type="t:ReplyBody" />
+ <xs:element minOccurs="0" maxOccurs="1" name="ExternalReply" type="t:ReplyBody" />
+ <xs:element minOccurs="0" maxOccurs="1" name="DeclineMeetingReply" type="t:ReplyBody" />
+ <xs:element minOccurs="0" maxOccurs="1" name="DeclineEventsForScheduledOOF" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="DeclineAllEventsForScheduledOOF" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="CreateOOFEvent" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="OOFEventSubject" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="AutoDeclineFutureRequestsWhenOOF" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="OOFEventID" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="EventsToDeleteIDs" type="t:ArrayOfEventIDType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="OofSettings" type="t:UserOofSettings" />
+ <xs:element name="UserOofSettings" type="t:UserOofSettings" />
+
+ <!-- Value used in Message Xml -->
+ <xs:complexType name="Value">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="Name" type="xs:string" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="Value" type="t:Value"/>
+
+ <!-- ApprovalRequestDataType -->
+ <xs:complexType name="ApprovalRequestDataType">
+ <xs:sequence>
+ <xs:element name="IsUndecidedApprovalRequest" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="ApprovalDecision" type="xs:int" minOccurs="0"/>
+ <xs:element name="ApprovalDecisionMaker" type="xs:string" minOccurs="0"/>
+ <xs:element name="ApprovalDecisionTime" type="xs:dateTime" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- ReminderMessageDataType -->
+ <xs:complexType name="ReminderMessageDataType">
+ <xs:sequence>
+ <xs:element name="ReminderText" type="xs:string" minOccurs="0"/>
+ <xs:element name="Location" type="xs:string" minOccurs="0"/>
+ <xs:element name="StartTime" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="EndTime" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="AssociatedCalendarItemId" type="t:ItemIdType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- SendPromptType -->
+ <xs:simpleType name="SendPromptType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Send" />
+ <xs:enumeration value="VotingOption" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- VotingOptionDataType -->
+ <xs:complexType name="VotingOptionDataType">
+ <xs:sequence>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0"/>
+ <xs:element name="SendPrompt" type="t:SendPromptType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfVotingOptionDataType">
+ <xs:sequence>
+ <xs:element name="VotingOptionData" type="t:VotingOptionDataType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- VotingInformationType -->
+ <xs:complexType name="VotingInformationType">
+ <xs:sequence>
+ <xs:element name="UserOptions" type="t:ArrayOfVotingOptionDataType" minOccurs="0"/>
+ <xs:element name="VotingResponse" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- SP1 Id Conversion types -->
+ <xs:simpleType name="IdFormatType">
+ <xs:annotation>
+ <xs:documentation>Surfaces the various id types that are supported for conversion</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="EwsLegacyId"/>
+ <xs:enumeration value="EwsId"/>
+ <xs:enumeration value="EntryId"/>
+ <xs:enumeration value="HexEntryId"/>
+ <xs:enumeration value="StoreId"/>
+ <xs:enumeration value="OwaId"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="AlternateIdBaseType" abstract="true">
+ <xs:annotation>
+ <xs:documentation>
+ Surfaces alternate representations of an item or folder id. No change key is included.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="Format" type="t:IdFormatType" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="AlternateIdType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents an alternate mailbox folder or item Id.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:AlternateIdBaseType">
+ <xs:attribute name="Id" type="xs:string" use="required"/>
+ <xs:attribute name="Mailbox" type="t:NonEmptyStringType" use="required"/>
+ <xs:attribute name="IsArchive" type="xs:boolean" use="optional"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AlternatePublicFolderIdType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents an alternate public folder Id.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:AlternateIdBaseType">
+ <xs:attribute name="FolderId" type="xs:string" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AlternatePublicFolderItemIdType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents an alternate public folder item Id.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:AlternatePublicFolderIdType">
+ <xs:attribute name="ItemId" type="xs:string" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfAlternateIdsType">
+ <xs:annotation>
+ <xs:documentation>
+ A non-empty array of alternate Ids.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="AlternateId" type="t:AlternateIdType"/>
+ <xs:element name="AlternatePublicFolderId" type="t:AlternatePublicFolderIdType"/>
+ <xs:element name="AlternatePublicFolderItemId" type="t:AlternatePublicFolderItemIdType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="UserIdType">
+ <xs:sequence>
+ <xs:element name="SID" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PrimarySmtpAddress" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DistinguishedUser" type="t:DistinguishedUserType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ExternalUserIdentity" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="DistinguishedUserType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Default" />
+ <xs:enumeration value="Anonymous" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfPermissionsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Permission" type="t:PermissionType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfCalendarPermissionsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="CalendarPermission" type="t:CalendarPermissionType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfUnknownEntriesType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="UnknownEntry" type="xs:string" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:simpleType name="PermissionReadAccessType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="FullDetails" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="CalendarPermissionReadAccessType">
+ <xs:restriction base ="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="TimeOnly"/>
+ <xs:enumeration value="TimeAndSubjectAndLocation"/>
+ <xs:enumeration value="FullDetails"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="BasePermissionType" abstract="true">
+ <xs:annotation>
+ <xs:documentation>A permission on a folder</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="UserId" type="t:UserIdType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="CanCreateItems" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CanCreateSubFolders" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsFolderOwner" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsFolderVisible" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsFolderContact" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EditItems" type="t:PermissionActionType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DeleteItems" type="t:PermissionActionType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PermissionType">
+ <xs:annotation>
+ <xs:documentation>A permission on a folder</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:BasePermissionType">
+ <xs:sequence>
+ <xs:element name="ReadItems" type="t:PermissionReadAccessType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="PermissionLevel" type="t:PermissionLevelType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="CalendarPermissionType">
+ <xs:complexContent>
+ <xs:extension base="t:BasePermissionType">
+ <xs:sequence>
+ <xs:element name="ReadItems" type="t:CalendarPermissionReadAccessType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="CalendarPermissionLevel" type="t:CalendarPermissionLevelType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="PermissionActionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Owned" />
+ <xs:enumeration value="All" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="PermissionLevelType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Owner" />
+ <xs:enumeration value="PublishingEditor" />
+ <xs:enumeration value="Editor" />
+ <xs:enumeration value="PublishingAuthor" />
+ <xs:enumeration value="Author" />
+ <xs:enumeration value="NoneditingAuthor" />
+ <xs:enumeration value="Reviewer" />
+ <xs:enumeration value="Contributor" />
+ <xs:enumeration value="Custom" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="CalendarPermissionLevelType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Owner" />
+ <xs:enumeration value="PublishingEditor" />
+ <xs:enumeration value="Editor" />
+ <xs:enumeration value="PublishingAuthor" />
+ <xs:enumeration value="Author" />
+ <xs:enumeration value="NoneditingAuthor" />
+ <xs:enumeration value="Reviewer" />
+ <xs:enumeration value="Contributor" />
+ <xs:enumeration value="FreeBusyTimeOnly" />
+ <xs:enumeration value="FreeBusyTimeAndSubjectAndLocation" />
+ <xs:enumeration value="Custom" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="PermissionSetType">
+ <xs:annotation>
+ <xs:documentation>The set of permissions on a folder</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Permissions" type="t:ArrayOfPermissionsType" />
+ <xs:element name="UnknownEntries" type="t:ArrayOfUnknownEntriesType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="CalendarPermissionSetType">
+ <xs:annotation>
+ <xs:documentation>The set of permissions on a folder</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="CalendarPermissions" type="t:ArrayOfCalendarPermissionsType" />
+ <xs:element name="UnknownEntries" type="t:ArrayOfUnknownEntriesType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EffectiveRightsType">
+ <xs:sequence>
+ <xs:element name="CreateAssociated" type="xs:boolean" />
+ <xs:element name="CreateContents" type="xs:boolean" />
+ <xs:element name="CreateHierarchy" type="xs:boolean" />
+ <xs:element name="Delete" type="xs:boolean" />
+ <xs:element name="Modify" type="xs:boolean" />
+ <xs:element name="Read" type="xs:boolean" />
+ <xs:element name="ViewPrivateItems" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Delegate Management types -->
+
+ <xs:complexType name="ArrayOfDelegateUserType">
+ <xs:sequence>
+ <xs:element name="DelegateUser" type="t:DelegateUserType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfUserIdType">
+ <xs:sequence>
+ <xs:element name="UserId" type="t:UserIdType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="DeliverMeetingRequestsType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="DelegatesOnly"/>
+ <xs:enumeration value="DelegatesAndMe"/>
+ <xs:enumeration value="DelegatesAndSendInformationToMe"/>
+ <xs:enumeration value="NoForward"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="DelegateUserType">
+ <xs:sequence>
+ <xs:element name="UserId" type="t:UserIdType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="DelegatePermissions" type="t:DelegatePermissionsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ReceiveCopiesOfMeetingMessages" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ViewPrivateItems" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DelegatePermissionsType">
+ <xs:sequence>
+ <xs:element name="CalendarFolderPermissionLevel" type="t:DelegateFolderPermissionLevelType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="TasksFolderPermissionLevel" type="t:DelegateFolderPermissionLevelType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="InboxFolderPermissionLevel" type="t:DelegateFolderPermissionLevelType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContactsFolderPermissionLevel" type="t:DelegateFolderPermissionLevelType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="NotesFolderPermissionLevel" type="t:DelegateFolderPermissionLevelType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="JournalFolderPermissionLevel" type="t:DelegateFolderPermissionLevelType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="DelegateFolderPermissionLevelType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="Editor"/>
+ <xs:enumeration value="Reviewer"/>
+ <xs:enumeration value="Author"/>
+ <xs:enumeration value="Custom"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ConflictResultsType">
+ <xs:sequence>
+ <xs:element name="Count" type="xs:int"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- MailTips Types -->
+
+ <xs:simpleType name="MailTipTypes">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="All" />
+ <xs:enumeration value="OutOfOfficeMessage" />
+ <xs:enumeration value="MailboxFullStatus" />
+ <xs:enumeration value="CustomMailTip" />
+ <xs:enumeration value="ExternalMemberCount" />
+ <xs:enumeration value="TotalMemberCount" />
+ <xs:enumeration value="MaxMessageSize" />
+ <xs:enumeration value="DeliveryRestriction" />
+ <xs:enumeration value="ModerationStatus" />
+ <xs:enumeration value="InvalidRecipient" />
+ <xs:enumeration value="Scope" />
+ <xs:enumeration value="RecipientSuggestions" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:complexType name="OutOfOfficeMailTip">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="ReplyBody" type="t:ReplyBody"/>
+ <xs:element minOccurs="0" maxOccurs="1" name="Duration" type="t:Duration"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SmtpDomainList">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="Domain" type="t:SmtpDomain"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SmtpDomain">
+ <xs:attribute name="Name" type="xs:string" use="required"/>
+ <xs:attribute name="IncludeSubdomains" type="xs:boolean" use="optional"/>
+ </xs:complexType>
+
+ <xs:complexType name="MailTips">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="RecipientAddress" type="t:EmailAddressType" />
+ <xs:element minOccurs="1" maxOccurs="1" name="PendingMailTips" type="t:MailTipTypes" />
+ <xs:element minOccurs="0" maxOccurs="1" name="OutOfOffice" type="t:OutOfOfficeMailTip" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MailboxFull" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="CustomMailTip" type="xs:string" />
+ <xs:element minOccurs="0" maxOccurs="1" name="TotalMemberCount" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="ExternalMemberCount" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="MaxMessageSize" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="DeliveryRestricted" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="IsModerated" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="InvalidRecipient" type="xs:boolean" />
+ <xs:element minOccurs="0" maxOccurs="1" name="Scope" type="xs:int" />
+ <xs:element minOccurs="0" maxOccurs="1" name="RecipientSuggestions" type="t:ArrayOfRecipientSuggestionsType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRecipientSuggestionsType">
+ <xs:sequence>
+ <xs:element name="RecipientSuggestion" type="t:RecipientSuggestionType" minOccurs="0" maxOccurs="3" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="RecipientSuggestionType">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="DisplayName" type="xs:string" />
+ <xs:element minOccurs="1" maxOccurs="1" name="EmailAddress" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- GetServiceConfiguration Types -->
+ <xs:simpleType name="ServiceConfigurationType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="MailTips" />
+ <xs:enumeration value="UnifiedMessagingConfiguration" />
+ <xs:enumeration value="ProtectionRules" />
+ <xs:enumeration value="PolicyNudges" />
+ <xs:enumeration value="SharePointURLs" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:complexType name="ServiceConfiguration">
+ <!-- this 'base class' is available for ErrorCode / ErrorMessage
+ elements if those become necessary in the future. -->
+ </xs:complexType>
+
+ <xs:complexType name="MailTipsServiceConfiguration">
+ <xs:complexContent>
+ <xs:extension base="t:ServiceConfiguration">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="MailTipsEnabled" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="MaxRecipientsPerGetMailTipsRequest" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="MaxMessageSize" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="LargeAudienceThreshold" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="ShowExternalRecipientCount" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="InternalDomains" type="t:SmtpDomainList"/>
+ <xs:element minOccurs="1" maxOccurs="1" name="PolicyTipsEnabled" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="LargeAudienceCap" type="xs:int" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="UnifiedMessageServiceConfiguration">
+ <xs:complexContent>
+ <xs:extension base="t:ServiceConfiguration">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="UmEnabled" type="xs:boolean" />
+ <xs:element minOccurs="1" maxOccurs="1" name="PlayOnPhoneDialString" type="xs:string"/>
+ <xs:element minOccurs="1" maxOccurs="1" name="PlayOnPhoneEnabled" type="xs:boolean" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SharePointURLsServiceConfiguration">
+ <xs:complexContent>
+ <xs:extension base="t:ServiceConfiguration">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="InternalSPMySiteHostURL" type="xs:string" />
+ <xs:element minOccurs="1" maxOccurs="1" name="ExternalSPMySiteHostURL" type="xs:string" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ConfigurationRequestDetailsType">
+ <xs:choice minOccurs="1" maxOccurs="1">
+ <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded" namespace="##any"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- Sharing Types -->
+ <xs:complexType name="ArrayOfSmtpAddressType">
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="SmtpAddress" type="t:NonEmptyStringType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfEncryptedSharedFolderDataType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="EncryptedSharedFolderData" type="t:EncryptedSharedFolderDataType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="EncryptedSharedFolderDataType">
+ <xs:sequence>
+ <xs:element name="Token" type="t:EncryptedDataContainerType"/>
+ <xs:element name="Data" type="t:EncryptedDataContainerType"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EncryptedDataContainerType">
+ <xs:sequence>
+ <xs:any processContents="skip" namespace="##other"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfInvalidRecipientsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="InvalidRecipient" type="t:InvalidRecipientType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="InvalidRecipientType">
+ <xs:sequence>
+ <xs:element name="SmtpAddress" type="t:NonEmptyStringType"/>
+ <xs:element name="ResponseCode" type="t:InvalidRecipientResponseCodeType"/>
+ <xs:element name="MessageText" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="InvalidRecipientResponseCodeType">
+ <xs:annotation>
+ <xs:documentation>
+ Represents the message keys that can be returned for invalid recipients
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="OtherError"/>
+ <xs:enumeration value="RecipientOrganizationNotFederated"/>
+ <xs:enumeration value="CannotObtainTokenFromSTS"/>
+ <xs:enumeration value="SystemPolicyBlocksSharingWithThisRecipient"/>
+ <xs:enumeration value="RecipientOrganizationFederatedWithUnknownTokenIssuer"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="AcceptSharingInvitationType">
+ <xs:complexContent>
+ <xs:extension base="t:ReferenceItemResponseType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="SharingDataType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Calendar" />
+ <xs:enumeration value="Contacts" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- UMTypes -->
+ <xs:complexType name="PhoneCallIdType">
+ <xs:attribute name="Id" type="xs:string" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="PhoneCallInformationType">
+ <xs:sequence>
+ <xs:element name="PhoneCallState" type="t:PhoneCallStateType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ConnectionFailureCause" type="t:ConnectionFailureCauseType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SIPResponseText" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SIPResponseCode" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="PhoneCallStateType">
+ <xs:restriction base ="xs:string">
+ <xs:enumeration value="Idle"/>
+ <xs:enumeration value="Connecting"/>
+ <xs:enumeration value="Alerted"/>
+ <xs:enumeration value="Connected"/>
+ <xs:enumeration value="Disconnected"/>
+ <xs:enumeration value="Incoming"/>
+ <xs:enumeration value="Transferring"/>
+ <xs:enumeration value="Forwarding"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ConnectionFailureCauseType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="UserBusy"/>
+ <xs:enumeration value="NoAnswer"/>
+ <xs:enumeration value="Unavailable"/>
+ <xs:enumeration value="Other"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- UserConfiguration Types -->
+
+ <xs:complexType name="UserConfigurationNameType">
+ <xs:complexContent>
+ <xs:extension base="t:TargetFolderIdType">
+ <xs:attribute name="Name" type="t:NonEmptyStringType" use="required"/>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="UserConfigurationDictionaryObjectTypesType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="DateTime"/>
+ <xs:enumeration value="Boolean"/>
+ <xs:enumeration value="Byte"/>
+ <xs:enumeration value="String"/>
+ <xs:enumeration value="Integer32"/>
+ <xs:enumeration value="UnsignedInteger32"/>
+ <xs:enumeration value="Integer64"/>
+ <xs:enumeration value="UnsignedInteger64"/>
+ <xs:enumeration value="StringArray"/>
+ <xs:enumeration value="ByteArray"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="UserConfigurationDictionaryObjectType">
+ <xs:sequence>
+ <xs:element name="Type" type="t:UserConfigurationDictionaryObjectTypesType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="UserConfigurationDictionaryEntryType">
+ <xs:sequence>
+ <xs:element name="DictionaryKey" type="t:UserConfigurationDictionaryObjectType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="DictionaryValue" type="t:UserConfigurationDictionaryObjectType" nillable="true" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="UserConfigurationDictionaryType">
+ <xs:sequence>
+ <xs:element name="DictionaryEntry" type="t:UserConfigurationDictionaryEntryType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="UserConfigurationType">
+ <xs:sequence>
+ <xs:element name="UserConfigurationName" type="t:UserConfigurationNameType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Dictionary" type="t:UserConfigurationDictionaryType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="XmlData" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="BinaryData" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="UserConfigurationPropertyType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Id"/>
+ <xs:enumeration value="Dictionary"/>
+ <xs:enumeration value="XmlData"/>
+ <xs:enumeration value="BinaryData"/>
+ <xs:enumeration value="All"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:complexType name="ProtectionRulesServiceConfiguration">
+ <xs:complexContent>
+ <xs:extension base="t:ServiceConfiguration">
+ <xs:sequence>
+ <xs:element name="Rules" type="t:ArrayOfProtectionRulesType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="InternalDomains" type="t:SmtpDomainList" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <xs:attribute name="RefreshInterval" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfProtectionRulesType">
+ <xs:sequence>
+ <xs:element name="Rule" type="t:ProtectionRuleType" minOccurs="0" maxOccurs="unbounded">
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ProtectionRuleType">
+ <xs:sequence>
+ <xs:element name="Condition" type="t:ProtectionRuleConditionType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Action" type="t:ProtectionRuleActionType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="UserOverridable" type="xs:boolean" use="required" />
+ <xs:attribute name="Priority" use="required" >
+ <xs:simpleType>
+ <xs:restriction base="xs:int">
+ <xs:minInclusive value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="ProtectionRuleConditionType">
+ <xs:choice minOccurs="1" maxOccurs="1">
+ <xs:element name="AllInternal" type="t:ProtectionRuleAllInternalType" />
+ <xs:element name="And" type="t:ProtectionRuleAndType" />
+ <xs:element name="RecipientIs" type="t:ProtectionRuleRecipientIsType" />
+ <xs:element name="SenderDepartments" type="t:ProtectionRuleSenderDepartmentsType" />
+ <xs:element name="True" type="t:ProtectionRuleTrueType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ProtectionRuleAndType">
+ <xs:sequence>
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="AllInternal" type="t:ProtectionRuleAllInternalType" />
+ <xs:element name="And" type="t:ProtectionRuleAndType" />
+ <xs:element name="RecipientIs" type="t:ProtectionRuleRecipientIsType" />
+ <xs:element name="SenderDepartments" type="t:ProtectionRuleSenderDepartmentsType" />
+ <xs:element name="True" type="t:ProtectionRuleTrueType" />
+ </xs:choice>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ProtectionRuleRecipientIsType">
+ <xs:sequence>
+ <xs:element name="Value" type="t:ProtectionRuleValueType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ProtectionRuleSenderDepartmentsType">
+ <xs:sequence>
+ <xs:element name="Value" type="t:ProtectionRuleValueType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="ProtectionRuleTrueType">
+ <xs:restriction base="xs:string">
+ <xs:length value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ProtectionRuleAllInternalType">
+ <xs:restriction base="xs:string">
+ <xs:length value="0"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ProtectionRuleValueType">
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ProtectionRuleActionKindType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="RightsProtectMessage"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ProtectionRuleActionType">
+ <xs:sequence>
+ <xs:element name="Argument" type="t:ProtectionRuleArgumentType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:attribute name="Name" use="required" type="t:ProtectionRuleActionKindType" />
+ </xs:complexType>
+
+ <xs:complexType name="ProtectionRuleArgumentType">
+ <xs:attribute name="Value" use="required">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:minLength value="1"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+
+ <!-- Policy Nudge Rules -->
+
+ <xs:complexType name="PolicyNudgeRulesServiceConfiguration">
+ <xs:sequence>
+ <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded" namespace="##any"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfFolderIdType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="FolderId" type="t:FolderIdType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- SetTeamMailbox -->
+ <xs:simpleType name="TeamMailboxLifecycleStateType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Active" />
+ <xs:enumeration value="Closed" />
+ <xs:enumeration value="Unlinked" />
+ <xs:enumeration value="PendingDelete" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Report Message Action-->
+ <xs:simpleType name="ReportMessageActionType">
+ <xs:annotation>
+ <xs:documentation>Surfaces the various report message action types</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Junk"/>
+ <xs:enumeration value="NotJunk"/>
+ <xs:enumeration value="Phish"/>
+ <xs:enumeration value="Unsubscribe"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- MessageTracking -->
+ <xs:complexType name="FindMessageTrackingSearchResultType">
+ <xs:all>
+ <xs:element name="Subject" type="xs:string" />
+ <xs:element name="Sender" type="t:EmailAddressType" />
+ <xs:element name="PurportedSender" type="t:EmailAddressType" minOccurs="0"/>
+ <xs:element name="Recipients" type="t:ArrayOfRecipientsType" />
+ <xs:element name="SubmittedTime" type="xs:dateTime" />
+ <xs:element name="MessageTrackingReportId" type="t:NonEmptyStringType" />
+ <xs:element name="PreviousHopServer" type="t:NonEmptyStringType" minOccurs="0" />
+ <xs:element name="FirstHopServer" type="t:NonEmptyStringType" minOccurs="0" />
+ <xs:element name="Properties" type="t:ArrayOfTrackingPropertiesType" minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfFindMessageTrackingSearchResultType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="MessageTrackingSearchResult" type="t:FindMessageTrackingSearchResultType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:simpleType name="MessageTrackingReportTemplateType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Summary" />
+ <xs:enumeration value="RecipientPath" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="RecipientTrackingEventType">
+ <xs:all>
+ <xs:element name="Date" type="xs:dateTime" />
+ <xs:element name="Recipient" type="t:EmailAddressType" />
+ <xs:element name="DeliveryStatus" type="xs:string" />
+ <xs:element name="EventDescription" type="xs:string" />
+ <xs:element name="EventData" type="t:ArrayOfStringsType" minOccurs="0"/>
+ <xs:element name="Server" type="t:NonEmptyStringType" />
+ <xs:element name="InternalId" type="xs:nonNegativeInteger" />
+ <xs:element name="BccRecipient" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="HiddenRecipient" type="xs:boolean" minOccurs="0"/>
+ <xs:element name="UniquePathId" type="t:NonEmptyStringType" minOccurs="0"/>
+ <xs:element name="RootAddress" type="t:NonEmptyStringType" minOccurs="0"/>
+ <xs:element name="Properties" type="t:ArrayOfTrackingPropertiesType" minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="MessageTrackingReportType">
+ <xs:all>
+ <xs:element name="Sender" type="t:EmailAddressType" minOccurs="0"/>
+ <xs:element name="PurportedSender" type="t:EmailAddressType" minOccurs="0"/>
+ <xs:element name="Subject" type="xs:string" minOccurs="0"/>
+ <xs:element name="SubmitTime" type="xs:dateTime" minOccurs="0"/>
+ <xs:element name="OriginalRecipients" type="t:ArrayOfEmailAddressesType" minOccurs="0" />
+ <xs:element name="RecipientTrackingEvents" type="t:ArrayOfRecipientTrackingEventType" />
+ <xs:element name="Properties" type="t:ArrayOfTrackingPropertiesType" minOccurs="0" />
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="TrackingPropertyType">
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Value" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfTrackingPropertiesType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="TrackingPropertyType" type="t:TrackingPropertyType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfArraysOfTrackingPropertiesType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="ArrayOfTrackingPropertiesType" type="t:ArrayOfTrackingPropertiesType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRecipientTrackingEventType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="RecipientTrackingEvent" type="t:RecipientTrackingEventType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- Rules -->
+ <xs:complexType name="RulePredicateSizeRangeType">
+ <xs:annotation>
+ <xs:documentation>Size range type used for the WithinSizeRange rule predicate.</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="MinimumSize" type="xs:int" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MaximumSize" type="xs:int" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="RulePredicateDateRangeType">
+ <xs:annotation>
+ <xs:documentation>Date range type used for the WithinDateRange rule predicate.</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="StartDateTime" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndDateTime" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="FlaggedForActionType">
+ <xs:annotation>
+ <xs:documentation>Flagged for action enumeration, currently used in FlaggedForAction rule predicate</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Any" />
+ <xs:enumeration value="Call" />
+ <xs:enumeration value="DoNotForward" />
+ <xs:enumeration value="FollowUp" />
+ <xs:enumeration value="FYI" />
+ <xs:enumeration value="Forward" />
+ <xs:enumeration value="NoResponseNecessary" />
+ <xs:enumeration value="Read" />
+ <xs:enumeration value="Reply" />
+ <xs:enumeration value="ReplyToAll" />
+ <xs:enumeration value="Review" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="RulePredicatesType">
+ <xs:annotation>
+ <xs:documentation>Rule predicates, used as rule conditions or exceptions</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Categories" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContainsBodyStrings" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContainsHeaderStrings" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContainsRecipientStrings" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContainsSenderStrings" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContainsSubjectOrBodyStrings" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ContainsSubjectStrings" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FlaggedForAction" type="t:FlaggedForActionType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FromAddresses" type="t:ArrayOfEmailAddressesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FromConnectedAccounts" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="HasAttachments" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Importance" type="t:ImportanceChoicesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsApprovalRequest" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsAutomaticForward" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsAutomaticReply" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsEncrypted" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsMeetingRequest" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsMeetingResponse" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsNDR" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsPermissionControlled" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsReadReceipt" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsSigned" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsVoicemail" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ItemClasses" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MessageClassifications" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="NotSentToMe" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SentCcMe" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SentOnlyToMe" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SentToAddresses" type="t:ArrayOfEmailAddressesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SentToMe" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SentToOrCcMe" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Sensitivity" type="t:SensitivityChoicesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="WithinDateRange" type="t:RulePredicateDateRangeType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="WithinSizeRange" type="t:RulePredicateSizeRangeType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="RuleActionsType">
+ <xs:annotation>
+ <xs:documentation>Rule actions</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="AssignCategories" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CopyToFolder" type="t:TargetFolderIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Delete" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ForwardAsAttachmentToRecipients" type="t:ArrayOfEmailAddressesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ForwardToRecipients" type="t:ArrayOfEmailAddressesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MarkImportance" type="t:ImportanceChoicesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MarkAsRead" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MoveToFolder" type="t:TargetFolderIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="PermanentDelete" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="RedirectToRecipients" type="t:ArrayOfEmailAddressesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SendSMSAlertToRecipients" type="t:ArrayOfEmailAddressesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ServerReplyWithMessage" type="t:ItemIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="StopProcessingRules" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="RuleType">
+ <xs:annotation>
+ <xs:documentation>Rule type</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="RuleId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="DisplayName" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Priority" type="xs:int" minOccurs="1" maxOccurs="1" />
+ <xs:element name="IsEnabled" type="xs:boolean" minOccurs="1" maxOccurs="1" />
+ <xs:element name="IsNotSupported" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="IsInError" type="xs:boolean" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Conditions" type="t:RulePredicatesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Exceptions" type="t:RulePredicatesType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Actions" type="t:RuleActionsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRulesType">
+ <xs:annotation>
+ <xs:documentation>Array of rule objects</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Rule" type="t:RuleType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:simpleType name="RuleFieldURIType">
+ <xs:annotation>
+ <xs:documentation>Rule field URI enumerates all possible rule fields that could trigger validation error</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="RuleId" />
+ <xs:enumeration value="DisplayName" />
+ <xs:enumeration value="Priority" />
+ <xs:enumeration value="IsNotSupported" />
+ <xs:enumeration value="Actions" />
+ <xs:enumeration value="Condition:Categories" />
+ <xs:enumeration value="Condition:ContainsBodyStrings" />
+ <xs:enumeration value="Condition:ContainsHeaderStrings" />
+ <xs:enumeration value="Condition:ContainsRecipientStrings" />
+ <xs:enumeration value="Condition:ContainsSenderStrings" />
+ <xs:enumeration value="Condition:ContainsSubjectOrBodyStrings" />
+ <xs:enumeration value="Condition:ContainsSubjectStrings" />
+ <xs:enumeration value="Condition:FlaggedForAction" />
+ <xs:enumeration value="Condition:FromAddresses" />
+ <xs:enumeration value="Condition:FromConnectedAccounts" />
+ <xs:enumeration value="Condition:HasAttachments" />
+ <xs:enumeration value="Condition:Importance" />
+ <xs:enumeration value="Condition:IsApprovalRequest" />
+ <xs:enumeration value="Condition:IsAutomaticForward" />
+ <xs:enumeration value="Condition:IsAutomaticReply" />
+ <xs:enumeration value="Condition:IsEncrypted" />
+ <xs:enumeration value="Condition:IsMeetingRequest" />
+ <xs:enumeration value="Condition:IsMeetingResponse" />
+ <xs:enumeration value="Condition:IsNDR" />
+ <xs:enumeration value="Condition:IsPermissionControlled" />
+ <xs:enumeration value="Condition:IsReadReceipt" />
+ <xs:enumeration value="Condition:IsSigned" />
+ <xs:enumeration value="Condition:IsVoicemail" />
+ <xs:enumeration value="Condition:ItemClasses" />
+ <xs:enumeration value="Condition:MessageClassifications" />
+ <xs:enumeration value="Condition:NotSentToMe" />
+ <xs:enumeration value="Condition:SentCcMe" />
+ <xs:enumeration value="Condition:SentOnlyToMe" />
+ <xs:enumeration value="Condition:SentToAddresses" />
+ <xs:enumeration value="Condition:SentToMe" />
+ <xs:enumeration value="Condition:SentToOrCcMe" />
+ <xs:enumeration value="Condition:Sensitivity" />
+ <xs:enumeration value="Condition:WithinDateRange" />
+ <xs:enumeration value="Condition:WithinSizeRange" />
+ <xs:enumeration value="Exception:Categories" />
+ <xs:enumeration value="Exception:ContainsBodyStrings" />
+ <xs:enumeration value="Exception:ContainsHeaderStrings" />
+ <xs:enumeration value="Exception:ContainsRecipientStrings" />
+ <xs:enumeration value="Exception:ContainsSenderStrings" />
+ <xs:enumeration value="Exception:ContainsSubjectOrBodyStrings" />
+ <xs:enumeration value="Exception:ContainsSubjectStrings" />
+ <xs:enumeration value="Exception:FlaggedForAction" />
+ <xs:enumeration value="Exception:FromAddresses" />
+ <xs:enumeration value="Exception:FromConnectedAccounts" />
+ <xs:enumeration value="Exception:HasAttachments" />
+ <xs:enumeration value="Exception:Importance" />
+ <xs:enumeration value="Exception:IsApprovalRequest" />
+ <xs:enumeration value="Exception:IsAutomaticForward" />
+ <xs:enumeration value="Exception:IsAutomaticReply" />
+ <xs:enumeration value="Exception:IsEncrypted" />
+ <xs:enumeration value="Exception:IsMeetingRequest" />
+ <xs:enumeration value="Exception:IsMeetingResponse" />
+ <xs:enumeration value="Exception:IsNDR" />
+ <xs:enumeration value="Exception:IsPermissionControlled" />
+ <xs:enumeration value="Exception:IsReadReceipt" />
+ <xs:enumeration value="Exception:IsSigned" />
+ <xs:enumeration value="Exception:IsVoicemail" />
+ <xs:enumeration value="Exception:ItemClasses" />
+ <xs:enumeration value="Exception:MessageClassifications" />
+ <xs:enumeration value="Exception:NotSentToMe" />
+ <xs:enumeration value="Exception:SentCcMe" />
+ <xs:enumeration value="Exception:SentOnlyToMe" />
+ <xs:enumeration value="Exception:SentToAddresses" />
+ <xs:enumeration value="Exception:SentToMe" />
+ <xs:enumeration value="Exception:SentToOrCcMe" />
+ <xs:enumeration value="Exception:Sensitivity" />
+ <xs:enumeration value="Exception:WithinDateRange" />
+ <xs:enumeration value="Exception:WithinSizeRange" />
+ <xs:enumeration value="Action:AssignCategories" />
+ <xs:enumeration value="Action:CopyToFolder" />
+ <xs:enumeration value="Action:Delete" />
+ <xs:enumeration value="Action:ForwardAsAttachmentToRecipients" />
+ <xs:enumeration value="Action:ForwardToRecipients" />
+ <xs:enumeration value="Action:MarkImportance" />
+ <xs:enumeration value="Action:MarkAsRead" />
+ <xs:enumeration value="Action:MoveToFolder" />
+ <xs:enumeration value="Action:PermanentDelete" />
+ <xs:enumeration value="Action:RedirectToRecipients" />
+ <xs:enumeration value="Action:SendSMSAlertToRecipients" />
+ <xs:enumeration value="Action:ServerReplyWithMessage" />
+ <xs:enumeration value="Action:StopProcessingRules" />
+ <xs:enumeration value="IsEnabled" />
+ <xs:enumeration value="IsInError" />
+ <xs:enumeration value="Conditions" />
+ <xs:enumeration value="Exceptions" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="RuleValidationErrorCodeType">
+ <xs:annotation>
+ <xs:documentation>Rule validation error code describing what failed validation for each rule predicate or action.</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="ADOperationFailure" />
+ <xs:enumeration value="ConnectedAccountNotFound" />
+ <xs:enumeration value="CreateWithRuleId" />
+ <xs:enumeration value="EmptyValueFound" />
+ <xs:enumeration value="DuplicatedPriority" />
+ <xs:enumeration value="DuplicatedOperationOnTheSameRule" />
+ <xs:enumeration value="FolderDoesNotExist" />
+ <xs:enumeration value="InvalidAddress" />
+ <xs:enumeration value="InvalidDateRange" />
+ <xs:enumeration value="InvalidFolderId" />
+ <xs:enumeration value="InvalidSizeRange" />
+ <xs:enumeration value="InvalidValue" />
+ <xs:enumeration value="MessageClassificationNotFound" />
+ <xs:enumeration value="MissingAction" />
+ <xs:enumeration value="MissingParameter" />
+ <xs:enumeration value="MissingRangeValue" />
+ <xs:enumeration value="NotSettable" />
+ <xs:enumeration value="RecipientDoesNotExist" />
+ <xs:enumeration value="RuleNotFound" />
+ <xs:enumeration value="SizeLessThanZero" />
+ <xs:enumeration value="StringValueTooBig" />
+ <xs:enumeration value="UnsupportedAddress" />
+ <xs:enumeration value="UnexpectedError" />
+ <xs:enumeration value="UnsupportedRule" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="RuleValidationErrorType">
+ <xs:annotation>
+ <xs:documentation>Represents a single validation error on a particular rule property value, predicate property value or action property value</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="FieldURI" type="t:RuleFieldURIType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ErrorCode" type="t:RuleValidationErrorCodeType" minOccurs ="1" maxOccurs="1" />
+ <xs:element name="ErrorMessage" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="FieldValue" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRuleValidationErrorsType">
+ <xs:annotation>
+ <xs:documentation>Represents an array of rule validation errors</xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Error" type="t:RuleValidationErrorType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="RuleOperationType" abstract="true">
+ <xs:annotation>
+ <xs:documentation>Represents a rule operation to be performed</xs:documentation>
+ </xs:annotation>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRuleOperationsType">
+ <xs:annotation>
+ <xs:documentation>Represents an array of rule operations to be performed</xs:documentation>
+ </xs:annotation>
+ <xs:choice minOccurs="1" maxOccurs="unbounded">
+ <xs:element name="CreateRuleOperation" type="t:CreateRuleOperationType" />
+ <xs:element name="SetRuleOperation" type="t:SetRuleOperationType" />
+ <xs:element name="DeleteRuleOperation" type="t:DeleteRuleOperationType" />
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="CreateRuleOperationType">
+ <xs:complexContent>
+ <xs:extension base="t:RuleOperationType">
+ <xs:sequence>
+ <xs:element name="Rule" type="t:RuleType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SetRuleOperationType">
+ <xs:complexContent>
+ <xs:extension base="t:RuleOperationType">
+ <xs:sequence>
+ <xs:element name="Rule" type="t:RuleType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="DeleteRuleOperationType">
+ <xs:complexContent>
+ <xs:extension base="t:RuleOperationType">
+ <xs:sequence>
+ <xs:element name="RuleId" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="RuleOperationErrorType">
+ <xs:sequence>
+ <xs:element name="OperationIndex" type="xs:int" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ValidationErrors" type="t:ArrayOfRuleValidationErrorsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRuleOperationErrorsType">
+ <xs:sequence>
+ <xs:element name="RuleOperationError" type="t:RuleOperationErrorType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Begin of mailbox search related types section -->
+
+ <xs:simpleType name="SearchItemKindType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Email" />
+ <xs:enumeration value="Meetings" />
+ <xs:enumeration value="Tasks" />
+ <xs:enumeration value="Notes" />
+ <xs:enumeration value="Docs" />
+ <xs:enumeration value="Journals" />
+ <xs:enumeration value="Contacts" />
+ <xs:enumeration value="Im" />
+ <xs:enumeration value="Voicemail" />
+ <xs:enumeration value="Faxes" />
+ <xs:enumeration value="Posts" />
+ <xs:enumeration value="Rssfeeds" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfSearchItemKindsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of search item kind enum.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="SearchItemKind" type="t:SearchItemKindType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="UserMailboxType">
+ <xs:annotation>
+ <xs:documentation>
+ User Mailbox.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="Id" type="xs:string" use="required"/>
+ <xs:attribute name="IsArchive" type="xs:boolean" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfUserMailboxesType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of user mailbox.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="UserMailbox" type="t:UserMailboxType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SearchableMailboxType">
+ <xs:annotation>
+ <xs:documentation>
+ Searchable mailbox.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Guid" type="t:GuidType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="PrimarySmtpAddress" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsExternalMailbox" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ExternalEmailAddress" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsMembershipGroup" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ReferenceId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSearchableMailboxesType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of searchable mailbox.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="SearchableMailbox" type="t:SearchableMailboxType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="KeywordStatisticsSearchResultType">
+ <xs:annotation>
+ <xs:documentation>
+ Keyword statistics search result.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Keyword" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ItemHits" type="xs:int" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Size" type="xs:long" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfKeywordStatisticsSearchResultsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of keyword statistics result.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="KeywordStat" type="t:KeywordStatisticsSearchResultType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxStatisticsSearchResultType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailbox statistics search result.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="UserMailbox" type="t:UserMailboxType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="KeywordStatisticsSearchResult" type="t:KeywordStatisticsSearchResultType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <xs:complexType name="ExtendedAttributeType">
+ <xs:annotation>
+ <xs:documentation>
+ Extended attributes of a target mailbox.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfExtendedAttributesType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of extended attributes of a target mailbox
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="ExtendedAttribute" type="t:ExtendedAttributeType" minOccurs="0" maxOccurs="unbounded" nillable="false"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="MailboxSearchLocationType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="PrimaryOnly" />
+ <xs:enumeration value="ArchiveOnly" />
+ <xs:enumeration value="All" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="MailboxSearchScopeType">
+ <xs:annotation>
+ <xs:documentation>
+ Set of mailbox, search scope and its extended attributes.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Mailbox" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SearchScope" type="t:MailboxSearchLocationType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ExtendedAttributes" type="t:ArrayOfExtendedAttributesType" minOccurs="0" maxOccurs="1" nillable="false"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfMailboxSearchScopesType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of mailbox and its search scope.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="MailboxSearchScope" type="t:MailboxSearchScopeType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxQueryType">
+ <xs:annotation>
+ <xs:documentation>
+ Pair of query and a set of mailbox search scopes.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Query" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="MailboxSearchScopes" type="t:NonEmptyArrayOfMailboxSearchScopesType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PreviewItemMailboxType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailbox information for each preview item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="MailboxId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="PrimarySmtpAddress" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfMailboxQueriesType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of query and mailboxes.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="MailboxQuery" type="t:MailboxQueryType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="SearchResultType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="StatisticsOnly" />
+ <xs:enumeration value="PreviewOnly" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="SearchPageDirectionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Previous" />
+ <xs:enumeration value="Next" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="PreviewItemBaseShapeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Default" />
+ <xs:enumeration value="Compact" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NonEmptyArrayOfExtendedFieldURIsType">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="ExtendedFieldURI" type="t:PathToExtendedFieldType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="PreviewItemResponseShapeType">
+ <xs:sequence>
+ <xs:element name="BaseShape" type="t:PreviewItemBaseShapeType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="AdditionalProperties" type="t:NonEmptyArrayOfExtendedFieldURIsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SearchPreviewItemType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailbox search preview item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Id" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Mailbox" type="t:PreviewItemMailboxType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ParentId" type="t:ItemIdType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ItemClass" type="t:ItemClassType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="UniqueHash" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SortValue" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="OwaLink" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Sender" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ToRecipients" type="t:ArrayOfSmtpAddressType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CcRecipients" type="t:ArrayOfSmtpAddressType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="BccRecipients" type="t:ArrayOfSmtpAddressType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CreatedTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ReceivedTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SentTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Subject" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Size" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Preview" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Importance" type="t:ImportanceChoicesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Read" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="HasAttachment" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ExtendedProperties" type="t:NonEmptyArrayOfExtendedPropertyType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSearchPreviewItemsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of search preview item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="SearchPreviewItem" type="t:SearchPreviewItemType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FailedSearchMailboxType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailbox failed on search and its error message.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Mailbox" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ErrorCode" type="xs:int" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ErrorMessage" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsArchive" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfFailedSearchMailboxesType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of failed mailbox and error message.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="FailedMailbox" type="t:FailedSearchMailboxType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SearchMailboxesResultType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailboxes search result.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="SearchQueries" type="t:NonEmptyArrayOfMailboxQueriesType" minOccurs="1"/>
+ <xs:element name="ResultType" type="t:SearchResultType" minOccurs="1"/>
+ <xs:element name="ItemCount" type="xs:long" minOccurs="1"/>
+ <xs:element name="Size" type="xs:long" minOccurs="1"/>
+ <xs:element name="PageItemCount" type="xs:int" minOccurs="1"/>
+ <xs:element name="PageItemSize" type="xs:long" minOccurs="1"/>
+ <xs:element name="KeywordStats" type="t:ArrayOfKeywordStatisticsSearchResultsType" minOccurs="0"/>
+ <xs:element name="Items" type="t:ArrayOfSearchPreviewItemsType" minOccurs="0"/>
+ <xs:element name="FailedMailboxes" type="t:ArrayOfFailedSearchMailboxesType" minOccurs="0"/>
+ <xs:element name="Refiners" type="t:ArrayOfSearchRefinerItemsType" minOccurs="0"/>
+ <xs:element name="MailboxStats" type="t:ArrayOfMailboxStatisticsItemsType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SearchRefinerItemType">
+ <xs:annotation>
+ <xs:documentation>
+ Search refiner item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Count" type="xs:long" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Token" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSearchRefinerItemsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of search refiner item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Refiner" type="t:SearchRefinerItemType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="OneDriveItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:annotation>
+ <xs:documentation>
+ OneDrive search result item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="ResourceId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="FileItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:annotation>
+ <xs:documentation>
+ File search result item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+
+ <!-- File properties -->
+ <xs:element name="FileName" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileExtension" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileSize" type="xs:long" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileCreatedTime" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileModifiedTime" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="StorageProviderContext" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileID" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ItemReferenceId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ReferenceId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Sender" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ItemReceivedTime" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ItemPath" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="ItemSentTime" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="FileContexts" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="VisualizationContainerUrl" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="VisualizationContainerTitle" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="VisualizationAccessUrl" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Document file item type -->
+ <xs:complexType name="DocumentFileItemType">
+ <xs:complexContent>
+ <xs:extension base="t:FileItemType">
+ <xs:sequence>
+ <xs:element name="Author" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Title" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="LastModifiedBy" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="DelveItemType">
+ <xs:complexContent>
+ <xs:extension base="t:ItemType">
+ <xs:annotation>
+ <xs:documentation>
+ Delve search result item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="GraphNodeLogicalId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxStatisticsItemType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailbox statistics item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="MailboxId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ItemCount" type="xs:long" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Size" type="xs:long" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfMailboxStatisticsItemsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of mailbox statistics item.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="MailboxStat" type="t:MailboxStatisticsItemType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="HoldActionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Create" />
+ <xs:enumeration value="Update" />
+ <xs:enumeration value="Remove" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="HoldStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NotOnHold" />
+ <xs:enumeration value="Pending" />
+ <xs:enumeration value="OnHold" />
+ <xs:enumeration value="PartialHold" />
+ <xs:enumeration value="Failed" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="MailboxHoldStatusType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailbox hold status.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Mailbox" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Status" type="t:HoldStatusType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="AdditionalInfo" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfMailboxHoldStatusType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of mailbox hold status.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="MailboxHoldStatus" type="t:MailboxHoldStatusType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxHoldResultType">
+ <xs:annotation>
+ <xs:documentation>
+ Mailbox hold result.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="HoldId" type="xs:string"/>
+ <xs:element name="Query" type="xs:string" minOccurs="0"/>
+ <xs:element name="MailboxHoldStatuses" type="t:ArrayOfMailboxHoldStatusType"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfLegacyDNsType">
+ <xs:sequence>
+ <xs:element name="LegacyDN" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonIndexableItemStatisticType">
+ <xs:annotation>
+ <xs:documentation>
+ Non indexable item statistic.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Mailbox" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ItemCount" type="xs:long" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ErrorMessage" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfNonIndexableItemStatisticsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of non indexable item statistics.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="NonIndexableItemStatistic" type="t:NonIndexableItemStatisticType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="ItemIndexErrorType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="GenericError" />
+ <xs:enumeration value="Timeout" />
+ <xs:enumeration value="StaleEvent" />
+ <xs:enumeration value="MailboxOffline" />
+ <xs:enumeration value="AttachmentLimitReached" />
+ <xs:enumeration value="MarsWriterTruncation" />
+ <xs:enumeration value="DocumentParserFailure" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NonIndexableItemDetailType">
+ <xs:annotation>
+ <xs:documentation>
+ Non indexable item detail.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ErrorCode" type="t:ItemIndexErrorType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ErrorDescription" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsPartiallyIndexed" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsPermanentFailure" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SortValue" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="AttemptCount" type="xs:int" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="LastAttemptTime" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AdditionalInfo" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfNonIndexableItemDetailsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of non indexable item details.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="NonIndexableItemDetail" type="t:NonIndexableItemDetailType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonIndexableItemDetailResultType">
+ <xs:annotation>
+ <xs:documentation>
+ Non indexable item details result.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Items" type="t:ArrayOfNonIndexableItemDetailsType" minOccurs="0"/>
+ <xs:element name="FailedMailboxes" type="t:ArrayOfFailedSearchMailboxesType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DiscoverySearchConfigurationType">
+ <xs:annotation>
+ <xs:documentation>
+ Discovery search configuration.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="SearchId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SearchQuery" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SearchableMailboxes" type="t:ArrayOfSearchableMailboxesType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="InPlaceHoldIdentity" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ManagedByOrganization" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Language" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfDiscoverySearchConfigurationType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of discovery search configuration.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="DiscoverySearchConfiguration" type="t:DiscoverySearchConfigurationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- End of mailbox search related types section -->
+
+ <!-- Retention tag guid with retention tag type attribute -->
+ <xs:complexType name="RetentionTagType">
+ <xs:simpleContent>
+ <xs:extension base="t:GuidType">
+ <xs:attribute name="IsExplicit" type="xs:boolean" use="required" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="UserPhotoSizeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="HR48x48" />
+ <xs:enumeration value="HR64x64" />
+ <xs:enumeration value="HR96x96" />
+ <xs:enumeration value="HR120x120" />
+ <xs:enumeration value="HR240x240" />
+ <xs:enumeration value="HR360x360" />
+ <xs:enumeration value="HR432x432" />
+ <xs:enumeration value="HR504x504" />
+ <xs:enumeration value="HR648x648" />
+ <xs:enumeration value="HR1024xN" />
+ <xs:enumeration value="HR1920xN" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="UserPhotoTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="UserPhoto" />
+ <xs:enumeration value="ProfileHeaderPhoto" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- Begin of MRM related types section -->
+
+ <xs:simpleType name="ElcFolderType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Calendar"/>
+ <xs:enumeration value="Contacts"/>
+ <xs:enumeration value="DeletedItems"/>
+ <xs:enumeration value="Drafts"/>
+ <xs:enumeration value="Inbox"/>
+ <xs:enumeration value="JunkEmail"/>
+ <xs:enumeration value="Journal"/>
+ <xs:enumeration value="Notes"/>
+ <xs:enumeration value="Outbox"/>
+ <xs:enumeration value="SentItems"/>
+ <xs:enumeration value="Tasks"/>
+ <xs:enumeration value="All"/>
+ <xs:enumeration value="ManagedCustomFolder"/>
+ <xs:enumeration value="RssSubscriptions"/>
+ <xs:enumeration value="SyncIssues"/>
+ <xs:enumeration value="ConversationHistory"/>
+ <xs:enumeration value="Personal"/>
+ <xs:enumeration value="RecoverableItems"/>
+ <xs:enumeration value="NonIpmRoot"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="RetentionActionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="MoveToDeletedItems"/>
+ <xs:enumeration value="MoveToFolder"/>
+ <xs:enumeration value="DeleteAndAllowRecovery"/>
+ <xs:enumeration value="PermanentlyDelete"/>
+ <xs:enumeration value="MarkAsPastRetentionLimit"/>
+ <xs:enumeration value="MoveToArchive"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="RetentionPolicyTagType">
+ <xs:annotation>
+ <xs:documentation>
+ Retention policy tag.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="RetentionId" type="t:GuidType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="RetentionPeriod" type="xs:int" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Type" type="t:ElcFolderType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="RetentionAction" type="t:RetentionActionType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IsVisible" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="OptedInto" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsArchive" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfRetentionPolicyTagsType">
+ <xs:annotation>
+ <xs:documentation>
+ Array of retention policy tags.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="RetentionPolicyTag" type="t:RetentionPolicyTagType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="RetentionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Delete"/>
+ <xs:enumeration value="Archive"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- End of MRM related types section -->
+
+ <!-- Begin of Client Extensibility related types section -->
+
+ <xs:simpleType name="ClientExtensionProvidedToType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Everyone" />
+ <xs:enumeration value="SpecificUsers" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ClientExtensionTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Default" />
+ <xs:enumeration value="Private" />
+ <xs:enumeration value="MarketPlace" />
+ <xs:enumeration value="PrivateCatalog" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ClientExtensionScopeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="User" />
+ <xs:enumeration value="Organization" />
+ <xs:enumeration value="Default" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ClientExtensionType">
+ <xs:sequence>
+ <xs:element name="SpecificUsers" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Manifest" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute name="IsAvailable" type="xs:boolean" use="optional"/>
+ <xs:attribute name="IsMandatory" type="xs:boolean" use="optional"/>
+ <xs:attribute name="IsEnabledByDefault" type="xs:boolean" use="optional"/>
+ <xs:attribute name="ProvidedTo" type="t:ClientExtensionProvidedToType" use="optional"/>
+ <xs:attribute name="Type" type="t:ClientExtensionTypeType" use="optional"/>
+ <xs:attribute name="Scope" type="t:ClientExtensionScopeType" use="optional"/>
+ <xs:attribute name="MarketplaceAssetId" type="xs:string" use="optional"/>
+ <xs:attribute name="MarketplaceContentMarket" type="xs:string" use="optional"/>
+ <xs:attribute name="AppStatus" type="xs:string" use="optional"/>
+ <xs:attribute name="Etoken" type="xs:string" use="optional"/>
+ <xs:attribute name="InstalledDateTime" type="xs:string" use="optional"/>
+ </xs:complexType>
+
+ <xs:simpleType name="ConsentStateType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NotResponded"/>
+ <xs:enumeration value="NotConsented"/>
+ <xs:enumeration value="Consented"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <!-- End of Client Extensibility related types section -->
+
+ <!-- Begin of UCS related types section -->
+
+ <xs:complexType name="ImGroupType">
+ <xs:annotation>
+ <xs:documentation>
+ A Group on the ImContactList, with one or more members
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="DisplayName" type="t:NonEmptyStringType"/>
+ <xs:element name="GroupType" type="t:NonEmptyStringType"/>
+ <xs:element name="ExchangeStoreId" type="t:ItemIdType" minOccurs="0"/>
+ <xs:element name="MemberCorrelationKey" type="t:NonEmptyArrayOfItemIdsType" minOccurs="0"/>
+ <xs:element name="ExtendedProperties" type="t:NonEmptyArrayOfExtendedPropertyType" minOccurs="0"/>
+ <xs:element name="SmtpAddress" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfImGroupType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="ImGroup" type="t:ImGroupType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="ImItemListType">
+ <xs:annotation>
+ <xs:documentation>
+ IM Contact List
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Groups" type="t:ArrayOfImGroupType" minOccurs="0"/>
+ <xs:element name="Personas" type="t:ArrayOfPeopleType" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- UCS methods only allow specification of extended properties -->
+ <xs:complexType name="NonEmptyArrayOfExtendedFieldURIs">
+ <xs:choice maxOccurs="unbounded">
+ <xs:element name="ExtendedProperty" type="t:PathToExtendedFieldType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- End of UCS related types section -->
+ <!-- UM Mailbox Pin related types section -->
+
+ <xs:simpleType name="DisableReasonType">
+ <xs:annotation>
+ <xs:documentation>List of possible reasons for disabling the client extension</xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NoReason"/>
+ <xs:enumeration value="OutlookClientPerformance" />
+ <xs:enumeration value="OWAClientPerformance" />
+ <xs:enumeration value="MobileClientPerformance" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NonEmptyStateDefinitionType">
+ <xs:choice minOccurs="0">
+ <xs:element name="DeletedOccurrenceStateDefinition" type="t:DeletedOccurrenceStateDefinitionType" />
+ <xs:element name="DeleteFromFolderStateDefinition" type="t:DeleteFromFolderStateDefinitionType"/>
+ <xs:element name="LocationBasedStateDefinition" type="t:LocationBasedStateDefinitionType"/>
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="BaseCalendarItemStateDefinitionType" />
+ <xs:complexType name="DeletedOccurrenceStateDefinitionType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseCalendarItemStateDefinitionType">
+ <xs:sequence>
+ <xs:element name="OccurrenceDate" type="xs:dateTime" minOccurs="1"/>
+ <xs:element name="IsOccurrencePresent" type="xs:boolean" minOccurs="0"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="DeleteFromFolderStateDefinitionType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseCalendarItemStateDefinitionType" />
+ </xs:complexContent>
+ </xs:complexType>
+ <xs:complexType name="LocationBasedStateDefinitionType">
+ <xs:complexContent>
+ <xs:extension base="t:BaseCalendarItemStateDefinitionType">
+ <xs:sequence>
+ <xs:element name="OrganizerLocation" type="xs:string" minOccurs="1"/>
+ <xs:element name="AttendeeLocation" type="xs:string" minOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="IconIndexType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Default" />
+ <xs:enumeration value="PostItem" />
+ <xs:enumeration value="MailRead" />
+ <xs:enumeration value="MailUnread" />
+ <xs:enumeration value="MailReplied" />
+ <xs:enumeration value="MailForwarded" />
+ <xs:enumeration value="MailEncrypted" />
+ <xs:enumeration value="MailSmimeSigned" />
+ <xs:enumeration value="MailEncryptedReplied" />
+ <xs:enumeration value="MailSmimeSignedReplied" />
+ <xs:enumeration value="MailEncryptedForwarded" />
+ <xs:enumeration value="MailSmimeSignedForwarded" />
+ <xs:enumeration value="MailEncryptedRead" />
+ <xs:enumeration value="MailSmimeSignedRead" />
+ <xs:enumeration value="MailIrm" />
+ <xs:enumeration value="MailIrmForwarded" />
+ <xs:enumeration value="MailIrmReplied" />
+ <xs:enumeration value="SmsSubmitted" />
+ <xs:enumeration value="SmsRoutedToDeliveryPoint" />
+ <xs:enumeration value="SmsRoutedToExternalMessagingSystem" />
+ <xs:enumeration value="SmsDelivered" />
+ <xs:enumeration value="OutlookDefaultForContacts" />
+ <xs:enumeration value="AppointmentItem" />
+ <xs:enumeration value="AppointmentRecur" />
+ <xs:enumeration value="AppointmentMeet" />
+ <xs:enumeration value="AppointmentMeetRecur" />
+ <xs:enumeration value="AppointmentMeetNY" />
+ <xs:enumeration value="AppointmentMeetYes" />
+ <xs:enumeration value="AppointmentMeetNo" />
+ <xs:enumeration value="AppointmentMeetMaybe" />
+ <xs:enumeration value="AppointmentMeetCancel" />
+ <xs:enumeration value="AppointmentMeetInfo" />
+ <xs:enumeration value="TaskItem" />
+ <xs:enumeration value="TaskRecur" />
+ <xs:enumeration value="TaskOwned" />
+ <xs:enumeration value="TaskDelegated" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="MeetingSpaceTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Public"/>
+ <xs:enumeration value="Private"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="MeetingSpaceType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ChangeKey" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Type" type="t:MeetingSpaceTypeEnum" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Version" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="JoinUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DateTimeCreated" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DateTimeModified" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ExpiryTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Meadata" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Tag" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="MeetingSpace" type="t:MeetingSpaceType"/>
+
+ <xs:simpleType name="ParticipantActivityRole">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Organizer" />
+ <xs:enumeration value="Attendee" />
+ <xs:enumeration value="Presenter" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ParticipantActivityMediaType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AppSharing" />
+ <xs:enumeration value="AudioVideo" />
+ <xs:enumeration value="Chat" />
+ <xs:enumeration value="DataConf" />
+ <xs:enumeration value="Meeting" />
+ <xs:enumeration value="MeetingConf" />
+ <xs:enumeration value="PhoneConf" />
+ <xs:enumeration value="Focus" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ParticipantActivity">
+ <xs:sequence>
+ <xs:element name="Id" type="t:GuidType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CreatedBy" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="StartTime" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="EndTime" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ClientVersion" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Role" type="t:ParticipantActivityRole" minOccurs="1" maxOccurs="1" />
+ <xs:element name="MediaType" type="t:ParticipantActivityMediaType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="MediaDetails" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfParticipantActivities">
+ <xs:sequence>
+ <xs:element name="ParticipantActivity" type="t:ParticipantActivity" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ContentActivity">
+ <xs:sequence>
+ <xs:element name="Id" type="t:GuidType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SharedBy" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="ContentLocation" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="StartTime" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="EndTime" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Type" type="t:ContentActivityType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="MediaType" type="t:ContentActivityMediaType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Acl" type="t:ContentActivityAcl" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="ContentActivityType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Poll" />
+ <xs:enumeration value="WhiteBoard" />
+ <xs:enumeration value="QAndA" />
+ <xs:enumeration value="Chat" />
+ <xs:enumeration value="Meeting" />
+ <xs:enumeration value="Annotations" />
+ <xs:enumeration value="SharedNotes" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ContentActivityMediaType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AppSharing" />
+ <xs:enumeration value="AudioVideo" />
+ <xs:enumeration value="Chat" />
+ <xs:enumeration value="DataConf" />
+ <xs:enumeration value="Meeting" />
+ <xs:enumeration value="MeetingConf" />
+ <xs:enumeration value="PhoneConf" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ContentActivityAcl">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Organizer" />
+ <xs:enumeration value="Presenter" />
+ <xs:enumeration value="Everyone" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="NonEmptyArrayOfContentActivities">
+ <xs:sequence>
+ <xs:element name="ContentActivity" type="t:ContentActivity" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingInstanceType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ChangeKey" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Version" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="JoinUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DateTimeCreated" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DateTimeModified" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Meadata" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Tag" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ParentGoid" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ParticipantActivities" type="t:NonEmptyArrayOfParticipantActivities" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ContentActivities" type="t:NonEmptyArrayOfContentActivities" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="MeetingInstance" type="t:MeetingInstanceType"/>
+
+ <!-- InstantSearch v2.0 DataTypes -->
+ <xs:simpleType name="WarmupOptionsType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="Suggestions"/>
+ <xs:enumeration value="Results"/>
+ <xs:enumeration value="All"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="SearchApplicationIdType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Outlook"/>
+ <xs:enumeration value="Owa"/>
+ <xs:enumeration value="Paw"/>
+ <xs:enumeration value="Teamspace"/>
+ <xs:enumeration value="OneDrive"/>
+ <xs:enumeration value="Other"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="ItemTypesFilterType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="MailItems"/>
+ <xs:enumeration value="MailConversations"/>
+ <xs:enumeration value="CalendarItems"/>
+ <xs:enumeration value="Contacts"/>
+ <xs:enumeration value="OneDriveItems"/>
+ <xs:enumeration value="FileItems"/>
+ <xs:enumeration value="DelveItems"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="SuggestionKindType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="Keywords"/>
+ <xs:enumeration value="People"/>
+ <xs:enumeration value="Hashtags"/>
+ <xs:enumeration value="QueryHistory"/>
+ <xs:enumeration value="All"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="RefinerTypeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None"/>
+ <xs:enumeration value="To"/>
+ <xs:enumeration value="From"/>
+ <xs:enumeration value="Folder"/>
+ <xs:enumeration value="HasAttachment"/>
+ <xs:enumeration value="MailboxSource"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="SearchResultsPropertySetNameType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Default"/>
+ <xs:enumeration value="Owa16"/>
+ <xs:enumeration value="Outlook16"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="SearchScopeGroupsType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="MyGroups"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="SearchScopeArchivesType">
+ <xs:list>
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="MainArchive"/>
+ <xs:enumeration value="AuxArchive"/>
+ <xs:enumeration value="All"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:list>
+ </xs:simpleType>
+
+ <xs:simpleType name="ExecuteSearchSortOrderType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="DateTime"/>
+ <xs:enumeration value="Relevance"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="MatchOptionsType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="FullString"/>
+ <xs:enumeration value="Prefix"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="SearchFolderScopeType">
+ <xs:choice>
+ <xs:element name="FolderId" type="t:FolderIdType"/>
+ <xs:element name="WellKnownFolder" type="t:DistinguishedFolderIdType"/>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name="PrimaryMailboxSearchScopeType">
+ <xs:sequence>
+ <xs:element name="FolderScope" type="t:SearchFolderScopeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IsDeepTraversal" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="LargeArchiveSearchScopeType">
+ <xs:sequence>
+ <xs:element name="ArchiveTypes" type="t:SearchScopeArchivesType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="GroupSearchScopeType">
+ <xs:sequence>
+ <xs:element name="GroupTypes" type="t:SearchScopeGroupsType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SingleLargeArchiveSearchScopeType">
+ <xs:sequence>
+ <xs:element name="MailboxGuid" type="t:GuidType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="FolderScope" type="t:SearchFolderScopeType" />
+ <xs:element name="IsDeepTraversal" type="xs:boolean"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="OneDriveSearchScopeType">
+ <xs:sequence>
+ <xs:element name="OneDriveView" type="t:OneDriveViewType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DelveSearchScopeType">
+ <xs:sequence>
+ <xs:element name="DelveView" type="t:DelveViewType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="CustomSearchScopeType">
+ <xs:sequence>
+ <xs:element name="MailboxGuid" type="t:GuidType"/>
+ <xs:element name="FolderScope" type="t:SearchFolderScopeType" />
+ <xs:element name="IsDeepTraversal" type="xs:boolean"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfSearchScopeType">
+ <xs:sequence>
+ <xs:element name="PrimaryMailboxSearchScope" type="t:PrimaryMailboxSearchScopeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LargeArchiveSearchScope" type="t:LargeArchiveSearchScopeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="GroupSearchScope" type="t:GroupSearchScopeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="CustomSearchScope" type="t:CustomSearchScopeType" minOccurs="0" maxOccurs="4"/>
+ <xs:element name="OneDriveSearchScope" type="t:OneDriveSearchScopeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SingleLargeArchiveSearchScope" type="t:SingleLargeArchiveSearchScopeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DelveSearchScope" type="t:DelveSearchScopeType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DynamicRefinerQueryType">
+ <xs:sequence>
+ <xs:element name="RefinerQuery" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="TDRefinerId" type="xs:int" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ExtendedKeywordDefinitionType">
+ <xs:sequence>
+ <xs:element name="Keyword" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Properties" type="t:NonEmptyArrayOfExtendedFieldURIsType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SuggestionType">
+ <xs:sequence>
+ <xs:element name="SuggestedQuery" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="DisplayText" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="SuggestionType" type="t:SuggestionKindType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Trigger" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="TDSuggestionId" type="xs:int"/>
+ <xs:element name="IsDeletable" type="xs:boolean"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="PeopleSuggestionType">
+ <xs:complexContent>
+ <xs:extension base="t:SuggestionType">
+ <xs:sequence>
+ <xs:element name="PrimarySmtpAddress" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="PersonType" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:simpleType name="PeopleSuggestionPersonType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Unknown"/>
+ <xs:enumeration value="Person"/>
+ <xs:enumeration value="DistributionList"/>
+ <xs:enumeration value="Room"/>
+ <xs:enumeration value="Place"/>
+ <xs:enumeration value="ModernGroup"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="FileSuggestionType">
+ <xs:complexContent>
+ <xs:extension base="t:SuggestionType">
+ <xs:sequence>
+ <xs:element name="FileName" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="FileExtension" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="FileReferenceId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="FileTitle" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ContainerTitle" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ContainerUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SearchSuggestionsType">
+ <xs:sequence>
+ <xs:element name="TDSuggestionsBatchId" type="xs:long" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="TDSuggestionsInstanceId" type="t:GuidType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Suggestions" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Suggestion" type="t:SuggestionType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DiagnosticsData" type="t:SearchDiagnosticsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="DeleteSearchSuggestionResponseType">
+ <xs:sequence>
+ <xs:element name="Success" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="StatusMessage" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DiagnosticsData" type="t:SearchDiagnosticsType" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SearchDiagnosticsStepType">
+ <xs:sequence>
+ <xs:element name="StartTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="StepTime" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="StepType" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AdditionalEntries" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Entry" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SearchRefinerType">
+ <xs:sequence>
+ <xs:element name="RefinerType" type="t:RefinerTypeType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="Refiner" type="t:DynamicRefinerQueryType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ResultCount" type="xs:long" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FolderRefinerType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchRefinerType">
+ <xs:sequence>
+ <xs:element name="FolderId" type="t:FolderIdType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="PeopleRefinerType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchRefinerType">
+ <xs:sequence>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SmtpAddress" type="t:SmtpAddressType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxRefinerType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchRefinerType">
+ <xs:sequence>
+ <xs:element name="MailboxDisplayName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="AttachmentRefinerType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchRefinerType">
+ <xs:sequence>
+ <xs:element name="HasAttachment" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="HashtagRefinerType">
+ <xs:complexContent>
+ <xs:extension base="t:SearchRefinerType">
+ <xs:sequence>
+ <xs:element name="DisplayName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SearchDiagnosticsType">
+ <xs:sequence>
+ <xs:sequence>
+ <xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded" namespace="##any"/>
+ </xs:sequence>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MailboxInformationType">
+ <xs:sequence>
+ <xs:sequence>
+ <xs:element name="MailboxGuid" type="t:GuidType"/>
+ <xs:element name="MailboxAddress" type="t:SmtpAddressType"/>
+ <xs:element name="MailboxDisplayName" type="xs:string"/>
+ </xs:sequence>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ExecuteSearchQueryIdType">
+ <xs:attribute name="Id" type="t:GuidType" use="required" />
+ </xs:complexType>
+
+ <xs:complexType name="SearchResultsType">
+ <xs:sequence>
+ <xs:element name="Items" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Item" type="t:ItemType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Conversations" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Conversation" type="t:ConversationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="People" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Persona" type="t:PersonaType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="MoreResultsAvailable" type="xs:boolean" minOccurs="1" maxOccurs="1" />
+ <xs:element name="RefinerTelemetryBatchId" type="xs:int" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SearchRefiners" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="SearchRefiner" type="t:SearchRefinerType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="DiagnosticsData" type="t:SearchDiagnosticsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SearchResultsCount" type="xs:int" minOccurs="0" maxOccurs="1" />
+ <xs:element name="TotalResultsCount" type="xs:int" minOccurs="0" maxOccurs="1" />
+ <xs:element name="SearchTerms" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="QueryId" type="t:ExecuteSearchQueryIdType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="MailboxesInformation" minOccurs="0" maxOccurs="1">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="MailboxInformation" type="t:MailboxInformationType" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="SearchResultItemIdType">
+ <xs:annotation>
+ <xs:documentation>Identifier for an item in search results</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:ItemIdType">
+ <xs:sequence>
+ <xs:element name="EntryId" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="OutlookItemId" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="SearchResultConversationIdType">
+ <xs:annotation>
+ <xs:documentation>Identifier for a conversation item in search results</xs:documentation>
+ </xs:annotation>
+ <xs:complexContent>
+ <xs:extension base="t:ItemIdType">
+ <xs:sequence>
+ <xs:element name="OutlookConversationId" type="xs:base64Binary" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <!-- Unified Groups -->
+ <xs:simpleType name="ClientIdType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Web" />
+ <xs:enumeration value="Mobile" />
+ <xs:enumeration value="Tablet" />
+ <xs:enumeration value="Desktop" />
+ <xs:enumeration value="Exchange" />
+ <xs:enumeration value="Outlook" />
+ <xs:enumeration value="MacOutlook" />
+ <xs:enumeration value="POP3" />
+ <xs:enumeration value="IMAP4" />
+ <xs:enumeration value="Other" />
+ <xs:enumeration value="Lync" />
+ <xs:enumeration value="OutlookService" />
+ <xs:enumeration value="MacMail" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="EntityFeedbackEntityAddSourceType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="EntityRelevanceApi" />
+ <xs:enumeration value="ActiveDirectory" />
+ <xs:enumeration value="ExplicitTyping" />
+ <xs:enumeration value="Paste" />
+ <xs:enumeration value="RecipientCache" />
+ <xs:enumeration value="Other" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfWorkHours">
+ <xs:sequence>
+ <xs:element name="WorkHours" type="t:WorkHoursType" minOccurs="0" maxOccurs="7" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="WorkHoursType">
+ <xs:sequence>
+ <xs:element name="WorkDay" type="t:SystemDayOfWeek" minOccurs="0" maxOccurs="1" />
+ <xs:element name="TimeSlots" type="t:ArrayOfWorkTimeSlot" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="SystemDayOfWeek">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Sunday" />
+ <xs:enumeration value="Monday" />
+ <xs:enumeration value="Tuesday" />
+ <xs:enumeration value="Wednesday" />
+ <xs:enumeration value="Thursday" />
+ <xs:enumeration value="Friday" />
+ <xs:enumeration value="Saturday" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfWorkTimeSlot">
+ <xs:sequence>
+ <xs:element name="TimeSlot" type="t:WorkTimeSlot" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="WorkTimeSlot">
+ <xs:sequence>
+ <xs:element minOccurs="1" maxOccurs="1" name="StartTimeInMinutes" type="xs:int" />
+ <xs:element minOccurs="1" maxOccurs="1" name="EndTimeInMinutes" type="xs:int" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AnalyzedQuery">
+ <xs:sequence>
+ <xs:element name="QueryLanguage" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="SearchRestrictions" type="t:RestrictionType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ContextPropertyType">
+ <xs:sequence>
+ <xs:element name="Key" type="xs:string" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Value" type="xs:string" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfContextProperty">
+ <xs:sequence>
+ <xs:element name="ContextProperty" type="t:ContextPropertyType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfEntityFeedbackEntry">
+ <xs:sequence>
+ <xs:element name="EntityFeedbackEntry" type="t:EntityFeedbackEntryType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="EntityFeedbackEntryType">
+ <xs:sequence>
+ <xs:element name="ClientEventTimeUTC" type="xs:dateTime" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ClientEventTimeLocal" type="xs:dateTime" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ClientSessionId" type="t:GuidType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ClientVersion" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ClientId" type="t:ClientIdType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="EntrySequenceNumber" type="xs:int" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="TransactionId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EventType" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="TargetEntityList" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EntityAddSource" type="t:EntityFeedbackEntityAddSourceType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="JsonPropertyBag" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfInboxReminderType">
+ <xs:sequence>
+ <xs:element name="InboxReminder" type="t:InboxReminderType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="InboxReminderType">
+ <xs:sequence>
+ <xs:element name="Id" type="t:GuidType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ReminderOffset" type="xs:int" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Message" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IsOrganizerReminder" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="OccurrenceChange" type="t:EmailReminderChangeType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SendOption" type="t:EmailReminderSendOption" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="EmailReminderChangeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="None" />
+ <xs:enumeration value="Added" />
+ <xs:enumeration value="Override" />
+ <xs:enumeration value="Deleted" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="EmailReminderSendOption">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="NotSet" />
+ <xs:enumeration value="User" />
+ <xs:enumeration value="AllAttendees" />
+ <xs:enumeration value="Staff" />
+ <xs:enumeration value="Customer" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="InsightStatusType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Created" />
+ <xs:enumeration value="Active" />
+ <xs:enumeration value="Dismissed" />
+ <xs:enumeration value="Invalid" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="InsightContextItem">
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Val" type="xs:string" minOccurs="0" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfInsightContextItem">
+ <xs:sequence>
+ <xs:element name="Context" type="t:InsightContextItem" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="InsightItemType">
+ <xs:sequence>
+ <xs:element name="ItemId" type="t:ItemIdType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="InsightId" type="t:GuidType" minOccurs="1" maxOccurs="1" />
+ <xs:element name="Type" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="StartTimeUtc" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="EndTimeUtc" type="xs:dateTime" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Status" type="t:InsightStatusType" minOccurs="0" maxOccurs="1" />
+ <xs:element name="Version" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Context" type="t:ArrayOfInsightContextItem" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Text" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ApplicationsIds" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="SuggestedActions" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AppContexts" type="t:ArrayOfStringsType" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfInsightItemType">
+ <xs:sequence>
+ <xs:element name="Insight" type="t:InsightItemType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ResponseMessageInfoType">
+ <xs:sequence minOccurs="0">
+ <xs:element name="MessageText" type="xs:string" minOccurs="0"/>
+ <xs:element name="ResponseCode" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="ResponseClass" type="t:ResponseClassType" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="BaseAvailabilityCalendarViewType">
+ <xs:sequence>
+ <xs:element name="FreeBusyViewType" type="t:FreeBusyViewType" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfPeopleQuerySource">
+ <xs:sequence>
+ <xs:element name="Source" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="CalendarActivityDataType">
+ <xs:sequence>
+ <xs:element name="ActivityAction" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="ClientId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CasRequestId" type="t:GuidType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IndexSelected" type="xs:int" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Social fabric, @Mentions type -->
+ <xs:complexType name="MentionActionType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CreatedBy" type="t:EmailAddressExtendedType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CreatedDateTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ServerCreatedDateTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DeepLink" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Application" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Mentioned" type="t:EmailAddressExtendedType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="MentionText" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ClientReference" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfMentionActionsType">
+ <xs:sequence>
+ <xs:element name="MentionAction" type="t:MentionActionType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Social fabric, @Tag type -->
+ <xs:complexType name="AppliedHashtagType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CreatedBy" type="t:EmailAddressExtendedType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CreatedDateTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ServerCreatedDateTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DeepLink" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Application" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Tag" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsAutoTagged" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="IsInlined" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AppliedHashtagsPreviewType">
+ <xs:sequence>
+ <xs:element name="Hashtags" type="t:ArrayOfStringsType" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+
+ <xs:complexType name="NonEmptyArrayOfAppliedHashtagType">
+ <xs:sequence>
+ <xs:element name="AppliedHashtag" type="t:AppliedHashtagType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Social fabric, +1Like type -->
+ <xs:complexType name="LikeType">
+ <xs:sequence>
+ <xs:element name="Id" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CreatedBy" type="t:EmailAddressExtendedType" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="CreatedDateTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ServerCreatedDateTime" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="DeepLink" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Application" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="LikesPreviewType">
+ <xs:sequence>
+ <xs:element name="LikeCount" type="xs:int" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MentionsPreviewType">
+ <xs:sequence>
+ <xs:element name="IsMentioned" type="xs:boolean" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="NonEmptyArrayOfLikeType">
+ <xs:sequence>
+ <xs:element name="Like" type="t:LikeType" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- FindAvailableMeetingTimes Service Types -->
+ <xs:complexType name="AttendeeAvailability">
+ <xs:sequence>
+ <xs:element name="EmailAddress" type="xs:string" />
+ <xs:element name="Availability" type="t:AvailabilityStatusType" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfMeetingLocation">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="MeetingLocation" type="t:MeetingLocation" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfAttendeeAvailability">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="AttendeeAvailability" type="t:AttendeeAvailability" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingTimeCandidate">
+ <xs:sequence>
+ <xs:element name="MeetingTimeslot" type="t:TimeSlot" />
+ <xs:element name="Confidence" type="xs:double" />
+ <xs:element name="Score" type="xs:int" />
+ <xs:element name="OrganizerAvailability" type="t:AvailabilityStatusType" />
+ <xs:element name="AttendeeAvailabilities" type="t:ArrayOfAttendeeAvailability" />
+ <xs:element name="Locations" type="t:ArrayOfMeetingLocation" />
+ <xs:element name="SuggestionHint" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfMeetingTimeCandidate">
+ <xs:sequence>
+ <xs:element name="MeetingTimeCandidate" type="t:MeetingTimeCandidate" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="MeetingTimeCandidatesConstraintItem">
+ <xs:sequence>
+ <xs:element name="Email" type="xs:string" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AttendeeConstraintItem">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingTimeCandidatesConstraintItem" >
+ <xs:sequence>
+ <xs:element name="IsRequired" type="xs:boolean" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="LocationConstraintItem">
+ <xs:complexContent>
+ <xs:extension base="t:MeetingTimeCandidatesConstraintItem" >
+ <xs:sequence>
+ <xs:element name="Name" type="xs:string" minOccurs="0" />
+ <xs:element name="ResolveAvailability" type="xs:boolean" minOccurs="0" />
+ </xs:sequence>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfLocationConstraintItems">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="LocationItem" type="t:LocationConstraintItem" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfAttendeeConstraintItems">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="AttendeeItem" type="t:AttendeeConstraintItem" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="ArrayOfTimeSlot">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="TimeSlot" type="t:TimeSlot" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="EmptySuggestionReason">
+ <xs:annotation>
+ <xs:documentation>
+ Reasons no suggestions are returned by FindMeetingTimeCandidates
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Unknown"/>
+ <xs:enumeration value="AttendeesUnavailable"/>
+ <xs:enumeration value="LocationsUnavailable"/>
+ <xs:enumeration value="OrganizerUnavailable"/>
+ <xs:enumeration value="AttendeesUnavailableOrUnknown"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="FindMeetingTimesAttendeeConstraints">
+ <xs:sequence>
+ <xs:element name="AttendeeEntries" type="t:ArrayOfAttendeeConstraintItems" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FindMeetingTimesLocationConstraints">
+ <xs:sequence>
+ <xs:element name="LocationEntries" type="t:ArrayOfLocationConstraintItems" minOccurs="0"/>
+ <xs:element name="IsRequired" type="xs:boolean" minOccurs="0" />
+ <xs:element name="SuggestLocation" type="xs:boolean" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FindMeetingTimesSearchConstraints">
+ <xs:sequence>
+ <xs:element name="SearchWindows" type="t:ArrayOfTimeSlot" minOccurs="0"/>
+ <xs:element name="MeetingDurationInMinutes" type="xs:int" minOccurs="0" />
+ <xs:element name="ActivityDomain" type="t:ActivityDomainType" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="FindMeetingTimesConstraints">
+ <xs:sequence>
+ <xs:element name="MaxCandidates" type="xs:int" minOccurs="0" />
+ <xs:element name="IsOrganizerOptional" type="xs:boolean" minOccurs="0" />
+ <xs:element name="ReturnSuggestionHints" type="xs:boolean" minOccurs="0" />
+ <xs:element name="AppName" type="xs:string" minOccurs="0" />
+ <xs:element name="AppScenario" type="xs:string" minOccurs="0" />
+ <xs:element name="MinimumAttendeePercentage" type="xs:double" minOccurs="0" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="AddInStateType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="Flagged"/>
+ <xs:enumeration value="OK"/>
+ <xs:enumeration value="Removed"/>
+ <xs:enumeration value="Undefined"/>
+ <xs:enumeration value="WithdrawingSoon"/>
+ <xs:enumeration value="Withdrawn"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="OfficeClientType">
+ <xs:attribute name="Code" type="t:OfficeClientCodeType" use="required"/>
+ <xs:attribute name="Version" type="t:VersionType" use="required"/>
+ </xs:complexType>
+
+ <xs:simpleType name="OfficeClientCodeType">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[a-zA-Z0-9]+_[a-zA-Z0-9]+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="VersionType">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[0-9]{1,4}\.[0-9]{1,4}(\.[0-9]{1,4}(\.[0-9]{1,4})?)?"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="ArrayOfAppsType">
+ <xs:sequence>
+ <xs:element name="App" type="t:AppType" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="Metadata" type="t:Metadata" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AppType">
+ <xs:sequence>
+ <xs:element name="Metadata" type="t:AppMetadata" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="Manifest" type="xs:base64Binary" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Metadata">
+ <xs:sequence>
+ <xs:element name="CustomApps" type="xs:string" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="AppMetadata">
+ <xs:sequence>
+ <xs:element name="EndNodeUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="AppStatus" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ActionUrl" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ProductId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="EnabledStatus" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ConsentState" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="ExtensionType" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="MarketplaceAssetId" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="LicenseStatus" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="TrialExpirationDate" type="xs:dateTime" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="InstalledBy" type="xs:string" minOccurs="0" maxOccurs="1"/>
+ <xs:element name="IsMandatory" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+</xs:schema>
diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php
new file mode 100644
index 00000000..21c77cbf
--- /dev/null
+++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php
@@ -0,0 +1,226 @@
+<?php
+/**
+ * Contains \JamesIArmes\PhpNtlm\NTLMSoapClient.
+ */
+
+namespace jamesiarmes\PhpNtlm;
+
+/**
+ * Soap Client using Microsoft's NTLM Authentication.
+ *
+ * @package php-ntlm\Soap
+ */
+class SoapClient extends \SoapClient
+{
+ /**
+ * cURL resource used to make the SOAP request
+ *
+ * @var resource
+ */
+ protected $ch;
+
+ /**
+ * Options passed to the client constructor.
+ *
+ * @var array
+ */
+ protected $options;
+
+ /**
+ * {@inheritdoc}
+ *
+ * Additional options:
+ * - user (string): The user to authenticate with.
+ * - password (string): The password to use when authenticating the user.
+ * - curlopts (array): Array of options to set on the curl handler when
+ * making the request.
+ * - strip_bad_chars (boolean, default true): Whether or not to strip
+ * invalid characters from the XML response. This can lead to content
+ * being returned differently than it actually is on the host service, but
+ * can also prevent the "looks like we got no XML document" SoapFault when
+ * the response includes invalid characters.
+ * - warn_on_bad_chars (boolean, default false): Trigger a warning if bad
+ * characters are stripped. This has no affect unless strip_bad_chars is
+ * true.
+ */
+ public function __construct($wsdl, array $options = null)
+ {
+ // Set missing indexes to their default value.
+ $options += array(
+ 'user' => null,
+ 'password' => null,
+ 'curlopts' => array(),
+ 'strip_bad_chars' => true,
+ 'warn_on_bad_chars' => false,
+ );
+ $this->options = $options;
+
+ // Verify that a user name and password were entered.
+ if (empty($options['user']) || empty($options['password'])) {
+ throw new \BadMethodCallException(
+ 'A username and password is required.'
+ );
+ }
+
+ parent::__construct($wsdl, $options);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __doRequest($request, $location, $action, $version, $one_way = 0)
+ {
+ $headers = $this->buildHeaders($action);
+ $this->__last_request = $request;
+ $this->__last_request_headers = $headers;
+
+ // Only reinitialize curl handle if the location is different.
+ if (!$this->ch
+ || curl_getinfo($this->ch, CURLINFO_EFFECTIVE_URL) != $location) {
+ $this->ch = curl_init($location);
+ }
+
+ curl_setopt_array($this->ch, $this->curlOptions($action, $request));
+ $response = curl_exec($this->ch);
+
+ // TODO: Add some real error handling.
+ // If the response if false than there was an error and we should throw
+ // an exception.
+ if ($response === false) {
+ $this->__last_response = $this->__last_response_headers = false;
+ throw new \RuntimeException(
+ 'Curl error: ' . curl_error($this->ch),
+ curl_errno($this->ch)
+ );
+ }
+
+ $this->parseResponse($response);
+ $this->cleanResponse();
+
+ return $this->__last_response;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function __getLastRequestHeaders()
+ {
+ return implode("\n", $this->__last_request_headers) . "\n";
+ }
+
+ /**
+ * Returns the response code from the last request
+ *
+ * @return integer
+ *
+ * @throws \BadMethodCallException
+ * If no cURL resource has been initialized.
+ */
+ public function getResponseCode()
+ {
+ if (empty($this->ch)) {
+ throw new \BadMethodCallException('No cURL resource has been '
+ . 'initialized. This is probably because no request has not '
+ . 'been made.');
+ }
+
+ return curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
+ }
+
+ /**
+ * Builds the headers for the request.
+ *
+ * @param string $action
+ * The SOAP action to be performed.
+ */
+ protected function buildHeaders($action)
+ {
+ return array(
+ 'Method: POST',
+ 'Connection: Keep-Alive',
+ 'User-Agent: PHP-SOAP-CURL',
+ 'Content-Type: text/xml; charset=utf-8',
+ "SOAPAction: \"$action\"",
+ 'Expect: 100-continue',
+ );
+ }
+
+ /**
+ * Cleans the response body by stripping bad characters if instructed to.
+ */
+ protected function cleanResponse()
+ {
+ // If the option to strip bad characters is not set, then we shouldn't
+ // do anything here.
+ if (!$this->options['strip_bad_chars']) {
+ return;
+ }
+
+ // Strip invalid characters from the XML response body.
+ $count = 0;
+ $this->__last_response = preg_replace(
+ '/(?!&#x0?(9|A|D))(&#x[0-1]?[0-9A-F];)/',
+ ' ',
+ $this->__last_response,
+ -1,
+ $count
+ );
+
+ // If the option to warn on bad characters is set, and some characters
+ // were stripped, then trigger a warning.
+ if ($this->options['warn_on_bad_chars'] && $count > 0) {
+ trigger_error(
+ 'Invalid characters were stripped from the XML SOAP response.',
+ E_USER_WARNING
+ );
+ }
+ }
+
+ /**
+ * Builds an array of curl options for the request
+ *
+ * @param string $action
+ * The SOAP action to be performed.
+ * @param string $request
+ * The XML SOAP request.
+ * @return array
+ * Array of curl options.
+ */
+ protected function curlOptions($action, $request)
+ {
+ $options = $this->options['curlopts'] + array(
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_HTTPHEADER => $this->buildHeaders($action),
+ CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+ CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_NTLM,
+ CURLOPT_USERPWD => $this->options['user'] . ':'
+ . $this->options['password'],
+ );
+
+ // We shouldn't allow these options to be overridden.
+ $options[CURLOPT_HEADER] = true;
+ $options[CURLOPT_POST] = true;
+ $options[CURLOPT_POSTFIELDS] = $request;
+
+ return $options;
+ }
+
+ /**
+ * Pareses the response from a successful request.
+ *
+ * @param string $response
+ * The response from the cURL request, including headers and body.
+ */
+ public function parseResponse($response)
+ {
+ // Parse the response and set the last response and headers.
+ $info = curl_getinfo($this->ch);
+ $this->__last_response_headers = substr(
+ $response,
+ 0,
+ $info['header_size']
+ );
+ $this->__last_response = substr($response, $info['header_size']);
+ }
+}
diff --git a/modules-available/locationinfo/frontend/frontendscript.js b/modules-available/locationinfo/frontend/frontendscript.js
index bad6a8ed..efe4d5b6 100644
--- a/modules-available/locationinfo/frontend/frontendscript.js
+++ b/modules-available/locationinfo/frontend/frontendscript.js
@@ -15,7 +15,7 @@ function IsOpen(date, room) {
openDate.setMinutes(tmp[i].MinutesOpen);
closeDate.setHours(tmp[i].HourClose);
closeDate.setMinutes(tmp[i].MinutesClose);
- if (openDate < date && closeDate > date) {
+ if (openDate <= date && closeDate > date) {
return true;
}
}
@@ -42,7 +42,7 @@ function toInt(str) {
* computes the time difference between 2 Date objects
* @param {Date} a
* @param {Date} b
- * @param {Array} globalConfig
+ * @param {Object} globalConfig
* @returns {string} printable time
*/
function GetTimeDiferenceAsString(a, b, globalConfig) {
diff --git a/modules-available/locationinfo/hooks/runmode/config.json b/modules-available/locationinfo/hooks/runmode/config.json
index 4dd7282f..4bba0b5f 100644
--- a/modules-available/locationinfo/hooks/runmode/config.json
+++ b/modules-available/locationinfo/hooks/runmode/config.json
@@ -3,5 +3,6 @@
"isClient": false,
"configHook": "LocationInfo::configHook",
"noSysconfig": true,
- "systemdDefaultTarget": "kiosk-mode"
+ "systemdDefaultTarget": "kiosk-mode",
+ "permission": ".locationinfo.panel.assign-client"
} \ No newline at end of file
diff --git a/modules-available/locationinfo/inc/coursebackend.inc.php b/modules-available/locationinfo/inc/coursebackend.inc.php
index 7162c885..dcd92f6f 100644
--- a/modules-available/locationinfo/inc/coursebackend.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend.inc.php
@@ -334,7 +334,7 @@ abstract class CourseBackend
{
$cleanresponse = preg_replace('/(<\/?)(\w+):([^>]*>)/', '$1$2$3', $response);
try {
- $xml = new SimpleXMLElement($cleanresponse);
+ $xml = @new SimpleXMLElement($cleanresponse); // This spams before throwing exception
} catch (Exception $e) {
$this->error = 'Could not parse reply as XML, got ' . get_class($e) . ': ' . $e->getMessage();
if (CONFIG_DEBUG) {
@@ -370,6 +370,9 @@ class BackendProperty {
* @param mixed $current current value of this property.
*/
public function initForRender($current = null) {
+ if ($current === null) {
+ $current = $this->default;
+ }
if (is_array($this->type)) {
$this->template = 'dropdown';
$this->select_list = [];
@@ -391,7 +394,7 @@ class BackendProperty {
} elseif ($this->type === 'password') {
$this->inputtype = Property::getPasswordFieldType();
}
- $this->currentvalue = $current === null ? $this->default : $current;
+ $this->currentvalue = $current;
}
public $inputtype;
public $template;
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php
index 8843e372..ed3d7ec2 100644
--- a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php
@@ -6,6 +6,10 @@ class CourseBackend_Davinci extends CourseBackend
private $location;
private $verifyHostname = true;
private $verifyCert = true;
+ /**
+ * @var bool|resource
+ */
+ private $curlHandle = false;
public function setCredentialsInternal($data)
{
@@ -69,7 +73,9 @@ class CourseBackend_Davinci extends CourseBackend
{
$url = $this->location . "content=xml&type=room&name=" . urlencode($roomId)
. "&startdate=" . $startDate->format('d.m.Y') . "&enddate=" . $endDate->format('d.m.Y');
- $ch = curl_init();
+ if ($this->curlHandle === false) {
+ $this->curlHandle = curl_init();
+ }
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
@@ -78,16 +84,15 @@ class CourseBackend_Davinci extends CourseBackend
CURLOPT_URL => $url,
);
- curl_setopt_array($ch, $options);
- $output = curl_exec($ch);
+ curl_setopt_array($this->curlHandle, $options);
+ $output = curl_exec($this->curlHandle);
if ($output === false) {
- $this->error = 'Curl error: ' . curl_error($ch);
+ $this->error = 'Curl error: ' . curl_error($this->curlHandle);
return false;
} else {
$this->error = false;
///Operation completed successfully
}
- curl_close($ch);
return $output;
}
@@ -142,4 +147,11 @@ class CourseBackend_Davinci extends CourseBackend
}
return $schedules;
}
+
+ public function __destruct()
+ {
+ if ($this->curlHandle !== false) {
+ curl_close($this->curlHandle);
+ }
+ }
}
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php
new file mode 100755
index 00000000..a62ea6d5
--- /dev/null
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php
@@ -0,0 +1,242 @@
+<?php
+
+/**
+ * Autoloader for the php-ews classes
+ */
+spl_autoload_register(function ($class) {
+ if (strpos($class, 'jamesiarmes') === false)
+ return;
+ $file = __DIR__ . '/../../exchange-includes/' . str_replace('\\', '/', $class) . '.php';
+ if (!file_exists($file))
+ return;
+ require_once $file;
+});
+
+use jamesiarmes\PhpEws\Client;
+use jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType;
+use jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType;
+use jamesiarmes\PhpEws\Enumeration\ItemQueryTraversalType;
+use jamesiarmes\PhpEws\Enumeration\ResponseClassType;
+use jamesiarmes\PhpEws\Request\FindItemType;
+use jamesiarmes\PhpEws\Request\ResolveNamesType;
+use jamesiarmes\PhpEws\Type\CalendarViewType;
+use jamesiarmes\PhpEws\Type\DistinguishedFolderIdType;
+use jamesiarmes\PhpEws\Type\EmailAddressType;
+use jamesiarmes\PhpEws\Type\ItemResponseShapeType;
+
+class CourseBackend_Exchange extends CourseBackend
+{
+
+ private $username = '';
+ private $password = '';
+ private $serverAddress;
+ private $clientVersion;
+ private $timezone = 'W. Europe Standard Time'; // TODO: make this configurable some time
+ private $verifyHostname = true;
+ private $verifyCert = true;
+
+ /**
+ * @return string return display name of backend
+ */
+ public function getDisplayName()
+ {
+ return "Microsoft Exchange";
+ }
+
+ /**
+ * @returns \BackendProperty[] list of properties that need to be set
+ */
+ public function getCredentialDefinitions()
+ {
+ $options = [
+ Client::VERSION_2007,
+ Client::VERSION_2007_SP1,
+ Client::VERSION_2009,
+ Client::VERSION_2010,
+ Client::VERSION_2010_SP1,
+ Client::VERSION_2010_SP2,
+ Client::VERSION_2013,
+ Client::VERSION_2013_SP1,
+ Client::VERSION_2016,
+ ];
+ return [
+ new BackendProperty('serverAddress', 'string'),
+ new BackendProperty('username', 'string'),
+ new BackendProperty('password', 'password'),
+ new BackendProperty('clientVersion', $options, Client::VERSION_2016),
+ new BackendProperty('verifyCert', 'bool', true),
+ new BackendProperty('verifyHostname', 'bool', true)
+ ];
+ }
+
+ /**
+ * @return boolean true if the connection works, false otherwise
+ */
+ public function checkConnection()
+ {
+ $client = $this->getClient();
+ $request = new ResolveNamesType();
+ $request->UnresolvedEntry = $this->username;
+ $request->ReturnFullContactData = false;
+
+ try {
+ $response = $client->ResolveNames($request);
+ } catch (Exception $e) {
+ $this->error = $e->getMessage();
+ return false;
+ }
+
+ try {
+ if ($response->ResponseMessages->ResolveNamesResponseMessage[0]->ResponseCode === "NoError") {
+ $mailadress = $response->ResponseMessages->ResolveNamesResponseMessage[0]->ResolutionSet->Resolution[0]->Mailbox->EmailAddress;
+ return !empty($mailadress);
+ }
+ } catch (Exception $e) {
+ $this->error = $e->getMessage();
+ }
+ return false;
+ }
+
+ /**
+ * uses json to setCredentials, the json must follow the form given in
+ * getCredentials
+ *
+ * @param array $data assoc array with data required by backend
+ * @returns bool if the credentials were in the correct format
+ */
+ public function setCredentialsInternal($data)
+ {
+ foreach (['username', 'password'] as $field) {
+ if (empty($data[$field])) {
+ $this->error = 'setCredentials: Missing field ' . $field;
+ return false;
+ }
+ }
+
+ if (empty($data['serverAddress'])) {
+ $this->error = "No url is given";
+ return false;
+ }
+
+ $this->username = $data['username'];
+ $this->password = $data['password'];
+
+ $this->serverAddress = $data['serverAddress'];
+ $this->clientVersion = $data['clientVersion'];
+
+ $this->verifyHostname = $data['verifyHostname'];
+ $this->verifyCert = $data['verifyCert'];
+
+ return true;
+ }
+
+ /**
+ * @return int desired caching time of results, in seconds. 0 = no caching
+ */
+ public function getCacheTime()
+ {
+ return 0;
+ }
+
+ /**
+ * @return int age after which timetables are no longer refreshed. should be
+ * greater than CacheTime.
+ */
+ public function getRefreshTime()
+ {
+ return 0;
+ }
+
+ /**
+ * Internal version of fetch, to be overridden by subclasses.
+ *
+ * @param $roomIds array with local ID as key and serverId as value
+ * @return array a recursive array that uses the roomID as key
+ * and has the schedule array as value. A shedule array contains an array in this format:
+ * ["start"=>'JJJJ-MM-DD HH:MM:SS',"end"=>'JJJJ-MM-DD HH:MM:SS',"title"=>string]
+ */
+ protected function fetchSchedulesInternal($requestedRoomIds)
+ {
+ $startDate = new DateTime('today 0:00');
+ $endDate = new DateTime('+7 days 0:00');
+ $client = $this->getClient();
+
+ $schedules = [];
+ foreach ($requestedRoomIds as $roomId) {
+ try {
+ $items = $this->findEventsForRoom($client, $startDate, $endDate, $roomId);
+ } catch (Exception $e) {
+ $this->error .= "Failed to search for events for room $roomId: '{$e->getMessage()}'\n";
+ continue;
+ }
+
+ // Iterate over the events that were found, printing some data for each.
+ foreach ($items as $item) {
+ $start = new DateTime($item->Start);
+ $end = new DateTime($item->End);
+
+ $schedules[$roomId][] = array(
+ 'title' => $item->Subject,
+ 'start' => $start->format('Y-m-d') . "T" . $start->format('G:i:s'),
+ 'end' => $end->format('Y-m-d') . "T" . $end->format('G:i:s')
+ );
+ }
+ }
+ return $schedules;
+ }
+
+ /**
+ * @param \jamesiarmes\PhpEws\Client $client
+ * @param \DateTime $startDate
+ * @param \DateTime $endDate
+ * @param string $roomAddress
+ * @return \jamesiarmes\PhpEws\Type\CalendarItemType[]
+ */
+ public function findEventsForRoom($client, $startDate, $endDate, $roomAddress)
+ {
+ $request = new FindItemType();
+ $request->Traversal = ItemQueryTraversalType::SHALLOW;
+ $request->ItemShape = new ItemResponseShapeType();
+ $request->ItemShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES;
+
+ $request->CalendarView = new CalendarViewType();
+ $request->CalendarView->StartDate = $startDate->format('c');
+ $request->CalendarView->EndDate = $endDate->format('c');
+ $folderId = new DistinguishedFolderIdType();
+ $folderId->Id = DistinguishedFolderIdNameType::CALENDAR;
+ $folderId->Mailbox = new EmailAddressType();
+ $folderId->Mailbox->EmailAddress = $roomAddress;
+ $request->ParentFolderIds->DistinguishedFolderId[] = $folderId;
+ $response = $client->FindItem($request);
+ $response_messages = $response->ResponseMessages->FindItemResponseMessage;
+
+ $items = [];
+ foreach ($response_messages as $response_message) {
+ // Make sure the request succeeded.
+ if ($response_message->ResponseClass !== ResponseClassType::SUCCESS) {
+ $code = $response_message->ResponseCode;
+ $message = $response_message->MessageText;
+ $this->error .= "Failed to search for events for room $roomAddress: '$code: $message'\n";
+ continue;
+ }
+ $items = array_merge($items, $response_message->RootFolder->Items->CalendarItem);
+ }
+ return $items;
+ }
+
+ /**
+ * @return \jamesiarmes\PhpEws\Client
+ */
+ public function getClient()
+ {
+ $client = new Client($this->serverAddress, $this->username, $this->password, $this->clientVersion);
+ $client->setTimezone($this->timezone);
+ $client->setCurlOptions(array(
+ CURLOPT_SSL_VERIFYPEER => $this->verifyHostname,
+ CURLOPT_SSL_VERIFYHOST => $this->verifyCert
+ ));
+
+ return $client;
+ }
+
+}
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
index 59bd9dc8..2ffb9f41 100644
--- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
@@ -8,6 +8,10 @@ class CourseBackend_HisInOne extends CourseBackend
private $location;
private $verifyHostname = true;
private $verifyCert = true;
+ /**
+ * @var bool|resource
+ */
+ private $curlHandle = false;
public function setCredentialsInternal($data)
@@ -27,7 +31,10 @@ class CourseBackend_HisInOne extends CourseBackend
}
$this->error = false;
- $this->username = $data['username'] . "\t" . $data['role'];
+ $this->username = $data['username'];
+ if (!empty($data['role'])) {
+ $this->username .= "\t" . $data['role'];
+ }
$this->password = $data['password'];
$this->open = $data['open'] !== 'CourseService';
$url = preg_replace('#(/+qisserver(/+services\d+(/+OpenCourseService)?)?)?\W*$#i', '', $data['baseUrl']);
@@ -60,7 +67,7 @@ class CourseBackend_HisInOne extends CourseBackend
if (empty($this->location)) {
$this->error = "Credentials are not set";
} else {
- $this->findUnit(123456789, true);
+ $this->findUnit(123456789, date('Y-m-d'), true);
}
return $this->error === false;
}
@@ -70,18 +77,8 @@ class CourseBackend_HisInOne extends CourseBackend
* @param bool $connectionCheckOnly true will only check if no soapError is returned, return value will be empty
* @return array|bool if successful an array with the event ids that take place in the room
*/
- public function findUnit($roomId, $connectionCheckOnly = false)
+ public function findUnit($roomId, $day, $connectionCheckOnly = false)
{
- $termYear = date('Y');
- $termType1 = date('n');
- if ($termType1 > 3 && $termType1 < 10) {
- $termType = 2;
- } elseif ($termType1 > 10) {
- $termType = 1;
- $termYear = $termYear + 1;
- } else {
- $termType = 1;
- }
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$envelope = $doc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'SOAP-ENV:Envelope');
@@ -90,18 +87,15 @@ class CourseBackend_HisInOne extends CourseBackend
$envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/OpenCourseService');
} else {
$envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/CourseService');
- $header = $this->getHeader($doc);
- $envelope->appendChild($header);
}
+ $header = $this->getHeader($doc);
+ $envelope->appendChild($header);
//Body of the request
$body = $doc->createElement('SOAP-ENV:Body');
$envelope->appendChild($body);
$findUnit = $doc->createElement('ns1:findUnit');
$body->appendChild($findUnit);
- $findUnit->appendChild($doc->createElement('termYear', $termYear));
- if ($termType1 != 3 && $termType1 != 10) {
- $findUnit->appendChild($doc->createElement('termTypeValueId', $termType));
- }
+ $findUnit->appendChild($doc->createElement('ns1:individualDatesExecutionDate', $day));
$findUnit->appendChild($doc->createElement('ns1:roomId', $roomId));
$soap_request = $doc->saveXML();
@@ -146,7 +140,7 @@ class CourseBackend_HisInOne extends CourseBackend
$idList = $this->getArrayPath($idSubDoc, $subpath);
if ($idList === false) {
$this->error = 'Cannot find ' . $subpath . ' after ' . $path;
- @file_put_contents('/tmp/findUnit-2.' . $roomId . '.' . microtime(true), print_r($idSubDoc, true));
+ @file_put_contents('/tmp/bwlp-findUnit-2.' . $roomId . '.' . microtime(true), print_r($idSubDoc, true));
}
return $idList;
}
@@ -188,7 +182,9 @@ class CourseBackend_HisInOne extends CourseBackend
"Content-length: " . strlen($request),
);
- $soap_do = curl_init();
+ if ($this->curlHandle === false) {
+ $this->curlHandle = curl_init();
+ }
$options = array(
CURLOPT_RETURNTRANSFER => true,
@@ -200,17 +196,16 @@ class CourseBackend_HisInOne extends CourseBackend
CURLOPT_HTTPHEADER => $header,
);
- curl_setopt_array($soap_do, $options);
+ curl_setopt_array($this->curlHandle, $options);
- $output = curl_exec($soap_do);
+ $output = curl_exec($this->curlHandle);
if ($output === false) {
- $this->error = 'Curl error: ' . curl_error($soap_do);
+ $this->error = 'Curl error: ' . curl_error($this->curlHandle);
} else {
$this->error = false;
///Operation completed successfully
}
- curl_close($soap_do);
return $output;
}
@@ -236,21 +231,28 @@ class CourseBackend_HisInOne extends CourseBackend
if (empty($requestedRoomIds)) {
return array();
}
+ $currentWeek = $this->getCurrentWeekDates();
$tTables = [];
//get all eventIDs in a given room
$eventIds = [];
foreach ($requestedRoomIds as $roomId) {
- $roomEventIds = $this->findUnit($roomId);
- if ($roomEventIds === false) {
- if ($this->error !== false) {
- error_log('Cannot findUnit(' . $roomId . '): ' . $this->error);
- $this->error = false;
+ $ok = false;
+ foreach ($currentWeek as $day) {
+ $roomEventIds = $this->findUnit($roomId, $day, false);
+ if ($roomEventIds === false) {
+ if ($this->error !== false) {
+ error_log('Cannot findUnit(' . $roomId . '): ' . $this->error);
+ $this->error = false;
+ }
+ // TODO: Error gets swallowed
+ continue;
}
- // TODO: Error gets swallowed
- continue;
+ $ok = true;
+ $eventIds = array_merge($eventIds, $roomEventIds);
+ }
+ if ($ok) {
+ $tTables[$roomId] = [];
}
- $tTables[$roomId] = [];
- $eventIds = array_merge($eventIds, $roomEventIds);
}
$eventIds = array_unique($eventIds);
if (empty($eventIds)) {
@@ -268,13 +270,12 @@ class CourseBackend_HisInOne extends CourseBackend
}
$eventDetails = array_merge($eventDetails, $event);
}
- $currentWeek = $this->getCurrentWeekDates();
$name = false;
+ $now = time();
foreach ($eventDetails as $event) {
foreach (array('/hisdefaulttext',
'/hisshorttext',
- '/hisshortcomment',
- '/hisplanelements/hisplanelement/hisdefaulttext') as $path) {
+ '/hisshortcomment') as $path) {
$name = $this->getArrayPath($event, $path);
if (!empty($name) && !empty($name[0]))
break;
@@ -283,25 +284,52 @@ class CourseBackend_HisInOne extends CourseBackend
if ($name === false) {
$name = ['???'];
}
- $unitPlannedDates = $this->getArrayPath($event,
- '/hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate');
- if ($unitPlannedDates === false) {
- $this->error = 'Cannot find ./hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate';
- error_log('Cannot find ./hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate');
+ $planElements = $this->getArrayPath($event, '/hisplanelements/hisplanelement');
+ if ($planElements === false) {
+ $this->error = 'Cannot find ./hisplanelements/hisplanelement';
+ error_log('Cannot find ./hisplanelements/hisplanelement');
error_log(print_r($event, true));
continue;
}
- foreach ($unitPlannedDates as $plannedDate) {
- $eventRoomId = $this->getArrayPath($plannedDate, '/hisroomId')[0];
- $eventDate = $this->getArrayPath($plannedDate, '/hisexecutiondate')[0];
- if (in_array($eventRoomId, $requestedRoomIds) && in_array($eventDate, $currentWeek)) {
- $startTime = $this->getArrayPath($plannedDate, '/hisstarttime')[0];
- $endTime = $this->getArrayPath($plannedDate, '/hisendtime')[0];
- $tTables[$eventRoomId][] = array(
- 'title' => $name[0],
- 'start' => $eventDate . "T" . $startTime,
- 'end' => $eventDate . "T" . $endTime
- );
+ foreach ($planElements as $planElement) {
+ if (empty($planElement['hisplannedDates']))
+ continue;
+ // Do not use -- is set improperly for some courses :-(
+ /*
+ $checkDate = $this->getArrayPath($planElement, '/hisplannedDates/hisplannedDate/hisenddate');
+ if (!empty($checkDate) && strtotime($checkDate[0]) + 86400 < $now)
+ continue; // Course ended
+ $checkDate = $this->getArrayPath($planElement, '/hisplannedDates/hisplannedDate/hisstartdate');
+ if (!empty($checkDate) && strtotime($checkDate[0]) - 86400 > $now)
+ continue; // Course didn't start yet
+ */
+ $cancelled = $this->getArrayPath($planElement, '/hiscancelled');
+ $cancelled = $cancelled !== false && is_array($cancelled) && ($cancelled[0] > 0 || strtolower($cancelled[0]) === 'true');
+ $unitPlannedDates = $this->getArrayPath($planElement,
+ '/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate');
+ if ($unitPlannedDates === false) {
+ $this->error = 'Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate';
+ error_log('Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate');
+ error_log(print_r($planElement, true));
+ continue;
+ }
+ $localName = $this->getArrayPath($planElement, '/hisdefaulttext');
+ if ($localName === false || empty($localName[0])) {
+ $localName = $name;
+ }
+ foreach ($unitPlannedDates as $plannedDate) {
+ $eventRoomId = $this->getArrayPath($plannedDate, '/hisroomId')[0];
+ $eventDate = $this->getArrayPath($plannedDate, '/hisexecutiondate')[0];
+ if (in_array($eventRoomId, $requestedRoomIds) && in_array($eventDate, $currentWeek)) {
+ $startTime = $this->getArrayPath($plannedDate, '/hisstarttime')[0];
+ $endTime = $this->getArrayPath($plannedDate, '/hisendtime')[0];
+ $tTables[$eventRoomId][] = array(
+ 'title' => $localName[0],
+ 'start' => $eventDate . "T" . $startTime,
+ 'end' => $eventDate . "T" . $endTime,
+ 'cancelled' => $cancelled,
+ );
+ }
}
}
}
@@ -323,9 +351,9 @@ class CourseBackend_HisInOne extends CourseBackend
$envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/OpenCourseService');
} else {
$envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/CourseService');
- $header = $this->getHeader($doc);
- $envelope->appendChild($header);
}
+ $header = $this->getHeader($doc);
+ $envelope->appendChild($header);
//body of the request
$body = $doc->createElement('SOAP-ENV:Body');
$envelope->appendChild($body);
@@ -359,10 +387,17 @@ class CourseBackend_HisInOne extends CourseBackend
{
$returnValue = array();
$startDate = time();
- for ($i = 0; $i <= 7; $i++) {
+ for ($i = 0; $i < 7; $i++) {
$returnValue[] = date('Y-m-d', strtotime("+{$i} day 12:00", $startDate));
}
return $returnValue;
}
+ public function __destruct()
+ {
+ if ($this->curlHandle !== false) {
+ curl_close($this->curlHandle);
+ }
+ }
+
}
diff --git a/modules-available/locationinfo/inc/coursebackend/exchange.todo b/modules-available/locationinfo/inc/coursebackend/exchange.todo
deleted file mode 100755
index 538f7382..00000000
--- a/modules-available/locationinfo/inc/coursebackend/exchange.todo
+++ /dev/null
@@ -1,203 +0,0 @@
-<?php
-
-require_once __DIR__ . '/../../vendor/autoload.php';
-
-use jamesiarmes\PhpEws\Client;
-use jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType;
-use jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType;
-use jamesiarmes\PhpEws\Enumeration\ItemQueryTraversalType;
-use jamesiarmes\PhpEws\Enumeration\ResponseClassType;
-use jamesiarmes\PhpEws\Request\FindItemType;
-use jamesiarmes\PhpEws\Request\ResolveNamesType;
-use jamesiarmes\PhpEws\Type\CalendarViewType;
-use jamesiarmes\PhpEws\Type\DistinguishedFolderIdType;
-use jamesiarmes\PhpEws\Type\EmailAddressType;
-use jamesiarmes\PhpEws\Type\ItemResponseShapeType;
-
-class CourseBackend_Exchange extends CourseBackend {
-
- private $username = '';
- private $password = '';
- private $baseUrl;
- private $client_version;
- private $timezone = 'W. Europe Standard Time'; // TODO: make this configurable some time
- private $verifyHostname = true;
- private $verifyCert = true;
-
- /**
- * @return string return display name of backend
- */
- public function getDisplayName() {
- return "Microsoft Exchange";
- }
-
- /**
- * @returns \BackendProperty[] list of properties that need to be set
- */
- public function getCredentialDefinitions() {
- $options = [Client::VERSION_2007, Client::VERSION_2007_SP1, Client::VERSION_2009, Client::VERSION_2010,
- Client::VERSION_2010_SP1, Client::VERSION_2010_SP2, Client::VERSION_2013, Client::VERSION_2013_SP1, Client::VERSION_2016];
- return [
- new BackendProperty('baseUrl', 'string'),
- new BackendProperty('username', 'string'),
- new BackendProperty('password', 'password'),
- new BackendProperty('client_version', $options),
- new BackendProperty('verifyCert', 'bool', true),
- new BackendProperty('verifyHostname', 'bool', true)
- ];
- }
-
- /**
- * @return boolean true if the connection works, false otherwise
- */
- public function checkConnection() {
- $client = $this->getClient();
- $request = new ResolveNamesType();
- $request->UnresolvedEntry = $this->username;
- $request->ReturnFullContactData = false;
-
- try {
- $response = $client->ResolveNames($request);
- } catch (Exception $e) {
- error_log("There was an error");
- error_log($e->getMessage());
- return false;
- }
-
- if ($response->ResponseMessages->ResolveNamesResponseMessage[0]->ResponseCode == "NoError") {
- $mailadress = $response->ResponseMessages->ResolveNamesResponseMessage[0]->ResolutionSet->Resolution[0]->Mailbox->EmailAddress;
- return !empty($mailadress);
- }
- return false;
- }
-
- /**
- * uses json to setCredentials, the json must follow the form given in
- * getCredentials
- *
- * @param array $data assoc array with data required by backend
- * @returns bool if the credentials were in the correct format
- */
- public function setCredentialsInternal($data) {
- foreach (['username', 'password'] as $field) {
- if (empty($data[$field])) {
- $this->error = 'setCredentials: Missing field ' . $field;
- return false;
- }
- }
-
- if (empty($data['baseUrl'])) {
- $this->error = "No url is given";
- return false;
- }
-
- $this->username = $data['username'];
- $this->password = $data['password'];
-
- $this->baseUrl = $data['baseUrl'];
- $this->client_version = $data['client_version'];
-
- $this->verifyHostname = $data['verifyHostname'];
- $this->verifyCert = $data['verifyCert'];
-
- return true;
- }
-
- /**
- * @return int desired caching time of results, in seconds. 0 = no caching
- */
- public function getCacheTime() {
- return 0;
- }
-
- /**
- * @return int age after which timetables are no longer refreshed should be
- * greater then CacheTime
- */
- public function getRefreshTime() {
- return 0;
- }
-
- /**
- * Internal version of fetch, to be overridden by subclasses.
- *
- * @param $roomIds array with local ID as key and serverId as value
- * @return array a recursive array that uses the roomID as key
- * and has the schedule array as value. A shedule array contains an array in this format:
- * ["start"=>'JJJJ-MM-DD HH:MM:SS',"end"=>'JJJJ-MM-DD HH:MM:SS',"title"=>string]
- */
- protected function fetchSchedulesInternal($requestedRoomIds) {
- $startDate = new DateTime('today 0:00');
- $endDate = new DateTime('+7 days 0:00');
- $client = $this->getClient();
-
- $schedules = [];
- foreach ($requestedRoomIds as $roomId) {
- $items = $this->findEventsForRoom($client, $startDate, $endDate, $roomId);
-
- // Iterate over the events that were found, printing some data for each.
- foreach ($items as $item) {
- $start = new DateTime($item->Start);
- $end = new DateTime($item->End);
-
- $schedules[$roomId][] = array(
- 'title' => $item->Subject,
- 'start' => $start->format('Y-m-d') . "T" . $start->format('G:i:s'),
- 'end' => $end->format('Y-m-d') . "T" . $end->format('G:i:s')
- );
- }
- }
- return $schedules;
- }
-
- public function findEventsForRoom($client, $start_date, $end_date, $email_room) {
- $request = new FindItemType();
- $request->Traversal = ItemQueryTraversalType::SHALLOW;
- $request->ItemShape = new ItemResponseShapeType();
- $request->ItemShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES;
-
- $request->CalendarView = new CalendarViewType();
- $request->CalendarView->StartDate = $start_date->format('c');
- $request->CalendarView->EndDate = $end_date->format('c');
- $folder_id = new DistinguishedFolderIdType();
- $folder_id->Id = DistinguishedFolderIdNameType::CALENDAR;
- $folder_id->Mailbox = new EmailAddressType();
- $folder_id->Mailbox->EmailAddress = $email_room;
- $request->ParentFolderIds->DistinguishedFolderId[] = $folder_id;
- $response = $client->FindItem($request);
- $response_messages = $response->ResponseMessages->FindItemResponseMessage;
-
- $items = [];
- foreach ($response_messages as $response_message) {
- // Make sure the request succeeded.
- if ($response_message->ResponseClass != ResponseClassType::SUCCESS) {
- $code = $response_message->ResponseCode;
- $message = $response_message->MessageText;
- error_log("Failed to search for events with \"$code: $message\"\n");
- continue;
- }
- $items = $response_message->RootFolder->Items->CalendarItem;
- }
- return $items;
- }
-
- public function getClient() {
- $client = new Client($this->baseUrl, $this->username, $this->password, $this->client_version);
- $client->setTimezone($this->timezone);
- $client->setCurlOptions(array(
- CURLOPT_SSL_VERIFYPEER => $this->verifyHostname,
- CURLOPT_SSL_VERIFYHOST => $this->verifyCert
- ));
-
- return $client;
- }
-
- function var_error_log($object = null) {
- ob_start(); // start buffer capture
- var_dump($object); // dump the values
- $contents = ob_get_contents(); // put the buffer into a variable
- ob_end_clean(); // end capture
- error_log($contents); // log contents of the result of var_dump( $object )
- }
-}
-?>
diff --git a/modules-available/locationinfo/inc/infopanel.inc.php b/modules-available/locationinfo/inc/infopanel.inc.php
index edeb9ccf..fdc253f0 100644
--- a/modules-available/locationinfo/inc/infopanel.inc.php
+++ b/modules-available/locationinfo/inc/infopanel.inc.php
@@ -37,6 +37,9 @@ class InfoPanel
$overrides = $json['overrides'];
}
unset($json['overrides']);
+ if (!isset($json['roomplanner'])) {
+ $config['roomplanner'] = false;
+ }
$config = $json + $config;
}
}
@@ -75,6 +78,8 @@ class InfoPanel
}
/**
+ * {"language":"de","mode":1,"vertical":true,"eco":false,"scaledaysauto":true,"daystoshow":7,"rotation":0,"scale":56,"switchtime":10,"calupdate":120,"roomupdate":20,
+ * "overrides": { "12" : { "mode":4} }
* Gets the location info of the given locations.
* Append to passed array which is expected to
* map location ids to properties of that location.
@@ -157,6 +162,8 @@ class InfoPanel
// Iterate over the locations we're actually interested in
$locations = Location::getLocationsAssoc();
foreach ($idList as $locationId) {
+ if (empty($locationId))
+ continue;
// Start checking at actual location...
$currentId = $locationId;
while ($currentId !== 0) {
@@ -175,6 +182,8 @@ class InfoPanel
}
}
// Keep trying with parent
+ if (!isset($locations[$currentId]))
+ break;
$currentId = $locations[$currentId]['parentlocationid'];
}
}
diff --git a/modules-available/locationinfo/inc/locationinfo.inc.php b/modules-available/locationinfo/inc/locationinfo.inc.php
index 38e271fe..377e960b 100644
--- a/modules-available/locationinfo/inc/locationinfo.inc.php
+++ b/modules-available/locationinfo/inc/locationinfo.inc.php
@@ -75,11 +75,12 @@ class LocationInfo
{
if ($type === 'DEFAULT') {
return array(
- 'language' => 'en',
+ 'language' => defined('LANG') ? LANG : 'en',
'mode' => 1,
'vertical' => false,
'eco' => false,
'prettytime' => true,
+ 'roomplanner' => true,
'scaledaysauto' => true,
'daystoshow' => 7,
'rotation' => 0,
@@ -92,10 +93,10 @@ class LocationInfo
}
if ($type === 'SUMMARY') {
return array(
- 'language' => 'en',
- 'calupdate' => 30,
- 'roomupdate' => 15,
- 'configupdate' => 180,
+ 'language' => defined('LANG') ? LANG : 'en',
+ 'roomplanner' => true,
+ 'eco' => false,
+ 'panelupdate' => 60,
);
}
return array();
@@ -127,11 +128,13 @@ class LocationInfo
} elseif ($row['paneltype'] === 'URL') {
// Check if we should set the insecure SSL mode (accept invalid/self signed certs etc.)
$data = json_decode($row['panelconfig'], true);
- if ($data && $data['insecure-ssl']) {
- ConfigHolder::add('SLX_BROWSER_INSECURE', '1');
- }
- if ($data && $data['reload-minutes']) {
- ConfigHolder::add('SLX_BROWSER_RELOAD_SECS', $data['reload-minutes'] * 60);
+ if (is_array($data)) {
+ if (isset($data['insecure-ssl']) && $data['insecure-ssl']) {
+ ConfigHolder::add('SLX_BROWSER_INSECURE', '1');
+ }
+ if (isset($data['reload-minutes']) && $data['reload-minutes']) {
+ ConfigHolder::add('SLX_BROWSER_RELOAD_SECS', $data['reload-minutes'] * 60);
+ }
}
}
ConfigHolder::add('SLX_BROWSER_URL', 'http://' . $_SERVER['SERVER_ADDR'] . '/panel/' . $panelUuid);
diff --git a/modules-available/locationinfo/inc/splittime.php.txt b/modules-available/locationinfo/inc/splittime.php.txt
new file mode 100644
index 00000000..53510fee
--- /dev/null
+++ b/modules-available/locationinfo/inc/splittime.php.txt
@@ -0,0 +1,80 @@
+(Unfinished)
+
+ /*
+ error_log('Pre calendar: ' . print_r($calendar, true));
+ $bad = array();
+ for ($i = 0; $i < count($calendar); ++$i) { // Use for..count as we append while iterating
+ $entry =& $calendar[$i];
+ // YYYY-MM-DD<T>HH:MM:SS
+ $s = explode('T', $entry['start']);
+ $e = explode('T', $entry['end']);
+ if (count($s) !== 2 || count($e) !== 2) {
+ error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry));
+ $bad[] = $i;
+ continue;
+ }
+ if ($e[0] === $s[0]) // Same day
+ continue;
+ $stime = explode(':', $s[1]);
+ $etime = explode(':', $e[1]);
+ if (count($stime) < 2 || count($etime) < 2) {
+ error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry));
+ $bad[] = $i;
+ continue;
+ }
+ // Fix start
+ if ($stime[0] == 23 && $stime[1] >= 30) {
+ // clamp to next day
+ $day = strtotime($s[0] . ' 12:00 +1 day');
+ if ($day === false || $day <= 0) {
+ error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry));
+ $bad[] = $i;
+ continue;
+ }
+ $day = date('Y-m-d', $day);
+ $bad[] = $i;
+ $calendar[] = array(
+ 'title' => $entry['title'],
+ 'start' => $day . 'T00:00:01',
+ 'end' => $entry['end']
+ );
+ continue;
+ }
+
+ // Fix end
+ if ($etime[0] == 0 && $etime[1] <= 30) {
+ // clamp to next day
+ $day = strtotime($e[0] . ' 12:00 -1 day');
+ if ($day === false || $day <= 0) {
+ error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry));
+ $bad[] = $i;
+ continue;
+ }
+ $day = date('Y-m-d', $day);
+ $bad[] = $i;
+ $calendar[] = array(
+ 'title' => $entry['title'],
+ 'start' => $day . 'T23:59:59',
+ 'end' => $entry['end']
+ );
+ continue;
+ }
+ // Split
+ $nextday = strtotime($s[0] . ' 12:00 +1 day');
+ $nextday = date('Y-m-d', $nextday);
+ $calendar[] = array(
+ 'title' => $entry['title'],
+ 'start' => $nextday . 'T00:00:01',
+ 'end' => $entry['end']
+ );
+ $entry['end'] = $s[0] . 'T23:59:59';
+ }
+ unset($entry);
+ if (!empty($bad)) {
+ foreach ($bad as $i) {
+ unset($calendar[$i]);
+ }
+ $calendar = array_values($calendar);
+ }
+ */
+ error_log('Post calendar: ' . print_r($calendar, true)); \ No newline at end of file
diff --git a/modules-available/locationinfo/lang/de/backend-exchange.json b/modules-available/locationinfo/lang/de/backend-exchange.json
new file mode 100644
index 00000000..51b4ed37
--- /dev/null
+++ b/modules-available/locationinfo/lang/de/backend-exchange.json
@@ -0,0 +1,14 @@
+{
+ "clientVersion": "Version",
+ "clientVersion_helptext": "Eingesetzte Exchange Version",
+ "password": "Passwort",
+ "password_helptext": "Passwort des Nutzers in Exchange",
+ "serverAddress": "Server-IP",
+ "serverAddress_helptext": "IP-Adresse des Exchange Servers",
+ "username": "Benutzername",
+ "username_helptext": "Benutzer muss mind. Reviewer Rechte auf Kalender besitzen",
+ "verifyCert": "Zertifikat pr\u00fcfen",
+ "verifyCert_helptext": "Wenn das Zertifikat abgelaufen ist, oder von keiner bekannten CA ausgestellt wurde, wird die Verbindung abgelehnt.",
+ "verifyHostname": "Hostnamen pr\u00fcfen",
+ "verifyHostname_helptext": "Der im Zertifikat angegebene Hostname muss mit dem Hostnamen aus der URL \u00fcbereinstimmen, sonst wird die Verbindung abgelehnt."
+} \ No newline at end of file
diff --git a/modules-available/locationinfo/lang/de/permissions.json b/modules-available/locationinfo/lang/de/permissions.json
new file mode 100644
index 00000000..1cd78eab
--- /dev/null
+++ b/modules-available/locationinfo/lang/de/permissions.json
@@ -0,0 +1,8 @@
+{
+ "backend.check": "Backend Verbindung pr\u00fcfen",
+ "backend.edit": "Backend bearbeiten",
+ "location.edit": "Raum\/Ort Einstellungen bearbeiten",
+ "panel.assign-client": "Client als Infoscreen festlegen",
+ "panel.edit": "Panel bearbeiten",
+ "panel.list": "Panel anzeigen"
+} \ No newline at end of file
diff --git a/modules-available/locationinfo/lang/de/template-tags.json b/modules-available/locationinfo/lang/de/template-tags.json
index bcdf7148..f9c7fad5 100644
--- a/modules-available/locationinfo/lang/de/template-tags.json
+++ b/modules-available/locationinfo/lang/de/template-tags.json
@@ -30,7 +30,8 @@
"lang_error": "Fehler",
"lang_expertMode": "Expertenmodus",
"lang_fourLocsHint": "Hier k\u00f6nnen Sie bis zu vier Orte ausw\u00e4hlen, die in diesem Panel angezeigt werden.",
- "lang_free": "Frei",
+ "lang_free": "Geöffnet",
+ "lang_for": "für",
"lang_general": "Allgemein",
"lang_ignoreSslTooltip": "Akzeptiere ung\u00fcltige, abgelaufene oder selbstsignierte SSL-Zertifikate",
"lang_insecureSsl": "Unsicheres SSL",
@@ -42,6 +43,7 @@
"lang_locations": "Orte",
"lang_locationsTable": "R\u00e4ume \/ Orte",
"lang_locationsTableHints": "Hier k\u00f6nnen Sie f\u00fcr die R\u00e4ume und Orte Ihrer Einrichtung \u00d6ffnungszeiten hinterlegen, sowie die Verkn\u00fcpfung mit Raum-IDs aus konfigurierten Backends (z.B. HISinOne) vornehmen, damit Belegungspl\u00e4ne abgerufen werden k\u00f6nnen.",
+ "lang_locsHint": "Hier k\u00f6nnen Sie die Orte ausw\u00e4hlen, die in diesem Panel angezeigt werden.",
"lang_longFri": "Freitag",
"lang_longMon": "Montag",
"lang_longSat": "Samstag",
@@ -57,7 +59,7 @@
"lang_modeTooltip": "Die Anzeigemodi, welche das Frontend unterst\u00fctzt",
"lang_monTilFr": "Montag - Freitag",
"lang_nameTooltip": "Legt den Namen des Servers fest",
- "lang_noLocationsWarning": "Sie haben keine Orte f\u00fcr dieses Panel ausgew\u00e4hlt",
+ "lang_noLocationsWarning": "Bitte w\u00e4hlen Sie mindestens einen Ort aus, der vom Panel angezeigt werden soll.",
"lang_noServer": "<Kein Server>",
"lang_openingTime": "\u00d6ffnungszeit",
"lang_openingtimes": "\u00d6ffnungszeiten",
@@ -76,7 +78,8 @@
"lang_remoteSchedule": "Abruf Belegungsplan",
"lang_room": "Raum",
"lang_roomId": "Raum ID",
- "lang_roomIdTooltip": "Die Raum ID, die der Server ben\u00f6tigt, um Kalenderdaten abzurufen",
+ "lang_roomIdTooltip": "Die Raum ID, die der Server ben\u00f6tigt, um Kalenderdaten abzurufen (bei Exchange die Postfachadresse)",
+ "lang_roomplannerTooltip": "Nur PCs berücksichtigen, die im Raumplaner gesetzt wurden",
"lang_roomupdateTooltip": "Zeit nach der die PCs aktualisiert werden (in Sekunden)",
"lang_rotation": "Rotation",
"lang_rotation0": "0\u00b0",
@@ -118,6 +121,7 @@
"lang_url": "URL",
"lang_urlPanel": "URL-Panel",
"lang_urlTooltip": "URL die aufgerufen wird",
+ "lang_useRoomplanner": "Raumplaner benutzen",
"lang_vertical": "Vertikaler Modus",
"lang_verticalTooltip": "Legt fest, ob Kalender und Raum \u00fcbereinander angezeigt werden sollen"
} \ No newline at end of file
diff --git a/modules-available/locationinfo/lang/en/backend-exchange.json b/modules-available/locationinfo/lang/en/backend-exchange.json
new file mode 100644
index 00000000..b3025d88
--- /dev/null
+++ b/modules-available/locationinfo/lang/en/backend-exchange.json
@@ -0,0 +1,14 @@
+{
+ "clientVersion": "Version",
+ "clientVersion_helptext": "Used exchange version",
+ "password": "Password",
+ "password_helptext": "User password in exchange",
+ "serverAddress": "Server-IP",
+ "serverAddress_helptext": "IP of the exchange server",
+ "username": "Username",
+ "username_helptext": "User needs at least reviewer rights on calendar",
+ "verifyCert": "Verify certificate",
+ "verifyCert_helptext": "If the certificate expired or was not signed by a known CA, the connection will be aborted",
+ "verifyHostname": "Verify host name",
+ "verifyHostname_helptext": "The certificate's host name must match the host name given in the URL, otherwise the connection will be aborted."
+} \ No newline at end of file
diff --git a/modules-available/locationinfo/lang/en/permissions.json b/modules-available/locationinfo/lang/en/permissions.json
new file mode 100644
index 00000000..4b620b04
--- /dev/null
+++ b/modules-available/locationinfo/lang/en/permissions.json
@@ -0,0 +1,8 @@
+{
+ "backend.check": "Test backend connection",
+ "backend.edit": "Edit backend",
+ "location.edit": "Edit location settings",
+ "panel.assign-client": "Set client as infoscreen",
+ "panel.edit": "Edit panel",
+ "panel.list": "List panels"
+} \ No newline at end of file
diff --git a/modules-available/locationinfo/lang/en/template-tags.json b/modules-available/locationinfo/lang/en/template-tags.json
index 558ddff0..5bbe3775 100644
--- a/modules-available/locationinfo/lang/en/template-tags.json
+++ b/modules-available/locationinfo/lang/en/template-tags.json
@@ -30,7 +30,8 @@
"lang_error": "Error",
"lang_expertMode": "Expert mode",
"lang_fourLocsHint": "You can pick up to four locations that will be shown in this panel.",
- "lang_free": "Free",
+ "lang_free": "Open",
+ "lang_for": "for",
"lang_general": "General",
"lang_ignoreSslTooltip": "Accept invalid, expired or self-signed ssl certificates",
"lang_insecureSsl": "Insecure SSL",
@@ -42,6 +43,7 @@
"lang_locations": "Locations",
"lang_locationsTable": "Rooms \/ Locations",
"lang_locationsTableHints": "Here you can define opening times for your locations and link the location ID to a configured backend (e.g. HISinOne) to show calendar events.",
+ "lang_locsHint": "You can pick up the locations that will be shown in this panel.",
"lang_longFri": "Friday",
"lang_longMon": "Monday",
"lang_longSat": "Saturday",
@@ -57,7 +59,7 @@
"lang_modeTooltip": "The display modes the frontend supports",
"lang_monTilFr": "Monday - Friday",
"lang_nameTooltip": "Defines the name of the server",
- "lang_noLocationsWarning": "Please select at least one location this panel should display",
+ "lang_noLocationsWarning": "Please select at least one location this panel should display.",
"lang_noServer": "<no server>",
"lang_openingTime": "Opening time",
"lang_openingtimes": "Opening times",
@@ -76,7 +78,8 @@
"lang_remoteSchedule": "Time table retrieval",
"lang_room": "Room",
"lang_roomId": "Room ID",
- "lang_roomIdTooltip": "The ID of the room the server needs, for querying the calendar data",
+ "lang_roomIdTooltip": "The ID of the room the server needs, for querying the calendar data (when using exchange the room mailbox)",
+ "lang_roomplannerTooltip": "Only consider PCs which were set in the roomplanner",
"lang_roomupdateTooltip": "Time the PCs in the room gets updated (in seconds)",
"lang_rotation": "Rotation",
"lang_rotation0": "0\u00b0",
@@ -118,6 +121,7 @@
"lang_url": "URL",
"lang_urlPanel": "URL panel",
"lang_urlTooltip": "URL which is shown by the panel",
+ "lang_useRoomplanner": "Use roomplans",
"lang_vertical": "Vertical mode",
"lang_verticalTooltip": "Defines whether the room and calendar are shown above each other"
} \ No newline at end of file
diff --git a/modules-available/locationinfo/page.inc.php b/modules-available/locationinfo/page.inc.php
index 777b84db..7be875d0 100644
--- a/modules-available/locationinfo/page.inc.php
+++ b/modules-available/locationinfo/page.inc.php
@@ -2,16 +2,15 @@
class Page_LocationInfo extends Page
{
-
- private $action;
+ private $show;
/**
* Called before any page rendering happens - early hook to check parameters etc.
*/
protected function doPreprocess()
{
- $show = Request::any('show', '', 'string');
- if ($show === 'panel') {
+ $this->show = Request::any('show', false, 'string');
+ if ($this->show === 'panel') {
$this->showPanel();
exit(0);
}
@@ -20,30 +19,38 @@ class Page_LocationInfo extends Page
Message::addError('main.no-permission');
Util::redirect('?do=Main'); // does not return
}
- $this->action = Request::post('action');
- if ($this->action === 'writePanelConfig') {
+ $action = Request::post('action');
+ if ($action === 'writePanelConfig') {
$this->writePanelConfig();
- } elseif ($this->action === 'writeLocationConfig') {
+ } elseif ($action === 'writeLocationConfig') {
$this->writeLocationConfig();
$show = 'locations';
- } elseif ($this->action === 'deleteServer') {
+ } elseif ($action === 'deleteServer') {
$this->deleteServer();
- } elseif ($this->action === 'deletePanel') {
+ } elseif ($action === 'deletePanel') {
$this->deletePanel();
- } elseif ($this->action === 'checkConnection') {
+ } elseif ($action === 'checkConnection') {
$this->checkConnection(Request::post('serverid', 0, 'int'));
$show = 'backends';
- } elseif ($this->action === 'updateServerSettings') {
+ } elseif ($action === 'updateServerSettings') {
$this->updateServerSettings();
$show = 'backends';
} elseif (Request::isPost()) {
- Message::addWarning('main.invalid-action', $this->action);
+ Message::addWarning('main.invalid-action', $action);
}
- if (Request::isPost()) {
+ if (Request::isPost() || $this->show === false) {
if (!empty($show)) {
- $show = '&show=' . $show;
+ //
+ } elseif (User::hasPermission('panel.list')) {
+ $show = 'panels';
+ } elseif (User::hasPermission('location.*')) {
+ $show = 'locations';
+ } elseif (User::hasPermission('backend.*')) {
+ $show = 'backends';
+ } else {
+ User::assertPermission('panel.list');
}
- Util::redirect('?do=locationinfo' . $show);
+ Util::redirect('?do=locationinfo&show=' . $show);
}
}
@@ -53,10 +60,13 @@ class Page_LocationInfo extends Page
protected function doRender()
{
// Do this here so we always see backend errors
- $backends = $this->loadBackends();
- $show = Request::get('show', '', 'string');
- Render::addTemplate('page-tabs', array('class-' . $show => 'active'));
- switch ($show) {
+ if (User::hasPermission('backend.*')) {
+ $backends = $this->loadBackends();
+ }
+ $data = array('class-' . $this->show => 'active');
+ Permission::addGlobalTags($data['perms'], null, ['backend.*', 'location.*', 'panel.list']);
+ Render::addTemplate('page-tabs', $data);
+ switch ($this->show) {
case 'locations':
$this->showLocationsTable();
break;
@@ -66,7 +76,7 @@ class Page_LocationInfo extends Page
case 'edit-panel':
$this->showPanelConfig();
break;
- case '':
+ case 'panels':
$this->showPanelsTable();
break;
default:
@@ -79,6 +89,7 @@ class Page_LocationInfo extends Page
*/
private function deleteServer()
{
+ User::assertPermission('backend.edit');
$id = Request::post('serverid', false, 'int');
if ($id === false) {
Message::addError('server-id-missing');
@@ -97,10 +108,14 @@ class Page_LocationInfo extends Page
Message::addError('main.parameter-missing', 'uuid');
return;
}
+ $this->assertPanelPermission($id, 'panel.edit');
$res = Database::exec("DELETE FROM `locationinfo_panel` WHERE paneluuid = :id", array('id' => $id));
if ($res !== 1) {
Message::addWarning('invalid-panel-id', $id);
}
+ if (Module::isAvailable('runmode')) {
+ RunMode::deleteMode(Page::getModule(), $id);
+ }
}
private function getTime($str)
@@ -123,6 +138,8 @@ class Page_LocationInfo extends Page
Message::addError('location.invalid-location-id', $locationid);
return false;
}
+ User::assertPermission('location.edit', $locationid);
+
$serverid = Request::post('serverid', 0, 'int');
if ($serverid === 0) {
$serverid = null;
@@ -304,6 +321,8 @@ class Page_LocationInfo extends Page
Util::redirect('?do=locationinfo');
}
+ // Permission
+ $this->assertPanelPermission($paneluuid, 'panel.edit', $params['locationids']);
if ($paneluuid === 'new') {
$paneluuid = Util::randomUuid();
@@ -340,6 +359,7 @@ class Page_LocationInfo extends Page
'vertical' => Request::post('vertical', false, 'bool'),
'eco' => Request::post('eco', false, 'bool'),
'prettytime' => Request::post('prettytime', false, 'bool'),
+ 'roomplanner' => Request::post('roomplanner', false, 'bool'),
'scaledaysauto' => Request::post('scaledaysauto', false, 'bool'),
'daystoshow' => Request::post('daystoshow', 7, 'int'),
'rotation' => Request::post('rotation', 0, 'int'),
@@ -369,9 +389,19 @@ class Page_LocationInfo extends Page
private function preparePanelConfigSummary()
{
+ // Build json structure
+ $conf = array(
+ 'language' => Request::post('language', 'en', 'string'),
+ 'eco' => Request::post('eco', false, 'bool'),
+ 'roomplanner' => Request::post('roomplanner', false, 'bool'),
+ 'panelupdate' => Request::post('panelupdate', 30, 'int')
+ );
+ if ($conf['panelupdate'] < 15) {
+ $conf['panelupdate'] = 15;
+ }
// Check locations
$locationids = self::getLocationIdsFromRequest(true);
- return array('locationids' => $locationids);
+ return array('config' => $conf, 'locationids' => $locationids);
}
/**
@@ -379,6 +409,7 @@ class Page_LocationInfo extends Page
*/
private function updateServerSettings()
{
+ User::assertPermission('backend.edit');
$serverid = Request::post('id', -1, 'int');
$servername = Request::post('name', 'unnamed', 'string');
$servertype = Request::post('type', '', 'string');
@@ -423,6 +454,7 @@ class Page_LocationInfo extends Page
if ($serverid === 0) {
Util::traceError('checkConnection called with no server id');
}
+ User::assertPermission('backend.check');
$dbresult = Database::queryFirst("SELECT servertype, credentials
FROM `locationinfo_coursebackend`
@@ -482,14 +514,22 @@ class Page_LocationInfo extends Page
*/
private function showBackendsTable($serverlist)
{
- // Pass the data to the html and render it.
- Render::addTemplate('page-servers', array(
+ User::assertPermission('backend.*');
+ $data = array(
'serverlist' => $serverlist,
- ));
+ );
+ Permission::addGlobalTags($data['perms'], null, ['backend.edit', 'backend.check']);
+ // Pass the data to the html and render it.
+ Render::addTemplate('page-servers', $data);
}
private function showLocationsTable()
{
+ $allowedLocations = User::getAllowedLocations('location.edit');
+ if (empty($allowedLocations)) {
+ Message::addError('main.no-permission');
+ return;
+ }
$locations = Location::getLocations(0, 0, false, true);
// Get hidden state of all locations
@@ -499,7 +539,7 @@ class Page_LocationInfo extends Page
while ($row = $dbquery->fetch(PDO::FETCH_ASSOC)) {
$locid = (int)$row['locationid'];
- if (!isset($locations[$locid]))
+ if (!isset($locations[$locid]) || !in_array($locid, $allowedLocations))
continue;
$glyph = !empty($row['openingtime']) ? 'ok' : '';
$backend = '';
@@ -517,6 +557,7 @@ class Page_LocationInfo extends Page
$stack = array();
$depth = -1;
foreach ($locations as &$location) {
+ $location['allowed'] = in_array($location['locationid'], $allowedLocations);
while ($location['depth'] <= $depth) {
array_pop($stack);
$depth--;
@@ -537,6 +578,13 @@ class Page_LocationInfo extends Page
private function showPanelsTable()
{
+ $visibleLocations = User::getAllowedLocations('panel.list');
+ $editLocations = User::getAllowedLocations('panel.edit');
+ $assignLocations = USer::getAllowedLocations('panel.assign-client');
+ if (empty($visibleLocations)) {
+ Message::addError('main.no-permission');
+ return;
+ }
$res = Database::simpleQuery('SELECT p.paneluuid, p.panelname, p.locationids, p.panelconfig,
p.paneltype FROM locationinfo_panel p
ORDER BY panelname ASC');
@@ -550,16 +598,25 @@ class Page_LocationInfo extends Page
if ($row['paneltype'] === 'URL') {
$url = json_decode($row['panelconfig'], true)['url'];
$row['locations'] = $row['locationurl'] = $url;
+ $row['edit_disabled'] = empty($editLocations) ? 'disabled' : '';
+ $row['runmode_disabled'] = empty($assignLocations) ? 'disabled' : '';
} else {
$lids = explode(',', $row['locationids']);
+ // Permissions
+ if (!empty(array_diff($lids, $visibleLocations))) {
+ continue;
+ }
+ $row['edit_disabled'] = !empty(array_diff($lids, $editLocations)) ? 'disabled' : '';
+ $row['runmode_disabled'] = !empty(array_diff($lids, $assignLocations)) ? 'disabled' : '';
+ // Locations
$locs = array_map(function ($id) use ($locations) {
return isset($locations[$id]) ? $locations[$id]['locationname'] : $id;
}, $lids);
$row['locations'] = implode(', ', $locs);
}
$len = mb_strlen($row['panelname']);
- if ($len < 5) {
- $row['panelname'] .= str_repeat('…', 5 - $len);
+ if ($len < 3) {
+ $row['panelname'] .= str_repeat(' ', 3 - $len);
}
if ($hasRunmode && isset($runmodes[$row['paneluuid']])) {
$row['assignedMachineCount'] = count($runmodes[$row['paneluuid']]);
@@ -594,6 +651,7 @@ class Page_LocationInfo extends Page
*/
private function ajaxServerSettings($id)
{
+ User::assertPermission('backend.edit');
$oldConfig = Database::queryFirst('SELECT servername, servertype, credentials
FROM `locationinfo_coursebackend` WHERE serverid = :id', array('id' => $id));
@@ -641,6 +699,7 @@ class Page_LocationInfo extends Page
*/
private function ajaxConfigLocation($id)
{
+ User::assertPermission('location.edit', $id);
$locConfig = Database::queryFirst("SELECT serverid, serverlocationid, openingtime FROM `locationinfo_locationconfig` WHERE locationid = :id", array('id' => $id));
if ($locConfig !== false) {
$openingtimes = json_decode($locConfig['openingtime'], true);
@@ -843,8 +902,14 @@ class Page_LocationInfo extends Page
}
$config = json_decode($panel['panelconfig'], true);
+ if (!isset($config['roomplanner'])) {
+ $config['roomplanner'] = false;
+ }
}
+ // Permission
+ $this->assertPanelPermission($panel, 'panel.edit');
+
$def = LocationInfo::defaultPanelConfig($panel['paneltype']);
if (!is_array($config)) {
$config = $def;
@@ -871,6 +936,7 @@ class Page_LocationInfo extends Page
'vertical_checked' => $config['vertical'] ? 'checked' : '',
'eco_checked' => $config['eco'] ? 'checked' : '',
'prettytime_checked' => $config['prettytime'] ? 'checked' : '',
+ 'roomplanner_checked' => $config['roomplanner'] ? 'checked' : '',
'scaledaysauto_checked' => $config['scaledaysauto'] ? 'checked' : '',
'daystoshow' => $config['daystoshow'],
'rotation' => $config['rotation'],
@@ -896,9 +962,11 @@ class Page_LocationInfo extends Page
'uuid' => $id,
'panelname' => $panel['panelname'],
'languages' => $langs,
- 'roomupdate' => $config['roomupdate'],
+ 'panelupdate' => $config['panelupdate'],
+ 'roomplanner_checked' => $config['roomplanner'] ? 'checked' : '',
'locations' => Location::getLocations(),
'locationids' => $panel['locationids'],
+ 'eco_checked' => $config['eco'] ? 'checked' : '',
));
}
}
@@ -934,7 +1002,7 @@ class Page_LocationInfo extends Page
'language' => $config['language'],
);
- die(Render::parse('frontend-default', $data));
+ die(Render::parse('frontend-default', $data, $module = false, $lang = $config['language']));
}
if ($type === 'SUMMARY') {
@@ -946,11 +1014,49 @@ class Page_LocationInfo extends Page
'language' => $config['language'],
);
- die(Render::parse('frontend-summary', $data));
+ die(Render::parse('frontend-summary', $data, $module = false, $lang = $config['language']));
}
http_response_code(500);
die('Unknown panel type ' . $type);
}
+ /**
+ * @param string|array $panelOrUuid UUID of panel, or array with keys paneltype and locationds
+ * @param string $permission
+ * @param null|int[] $additionalLocations
+ */
+ private function assertPanelPermission($panelOrUuid, $permission, $additionalLocations = null)
+ {
+ if (is_array($panelOrUuid)) {
+ $panel = $panelOrUuid;
+ } else {
+ $panel = Database::queryFirst('SELECT paneltype, locationids FROM locationinfo_panel
+ WHERE paneluuid = :uuid', ['uuid' => $panelOrUuid]);
+ }
+ if ($panel === false || $panel['paneltype'] === 'URL' || empty($panel['locationids'])) {
+ if (empty($additionalLocations)) {
+ User::assertPermission($permission, null, '?do=locationinfo');
+ return;
+ }
+ }
+ $allowed = User::getAllowedLocations($permission);
+ if (in_array(0, $allowed))
+ return;
+ if (!empty($allowed)) {
+ if (isset($panel['locationids'])) {
+ $locations = explode(',', $panel['locationids']);
+ } else {
+ $locations = [];
+ }
+ if (!empty($additionalLocations)) {
+ $locations = array_merge($locations, $additionalLocations);
+ }
+ if (empty(array_diff($locations, $allowed)))
+ return;
+ }
+ Message::addError('main.no-permission');
+ Util::redirect('?do=locationinfo');
+ }
+
}
diff --git a/modules-available/locationinfo/permissions/permissions.json b/modules-available/locationinfo/permissions/permissions.json
new file mode 100644
index 00000000..be95a7bd
--- /dev/null
+++ b/modules-available/locationinfo/permissions/permissions.json
@@ -0,0 +1,20 @@
+{
+ "backend.edit": {
+ "location-aware": false
+ },
+ "backend.check": {
+ "location-aware": false
+ },
+ "location.edit": {
+ "location-aware": true
+ },
+ "panel.list": {
+ "location-aware": true
+ },
+ "panel.edit": {
+ "location-aware": true
+ },
+ "panel.assign-client": {
+ "location-aware": true
+ }
+} \ No newline at end of file
diff --git a/modules-available/locationinfo/style.css b/modules-available/locationinfo/style.css
new file mode 100644
index 00000000..b5fffe75
--- /dev/null
+++ b/modules-available/locationinfo/style.css
@@ -0,0 +1,10 @@
+.btn-static {
+ background-color: white;
+ border: 1px solid lightgrey;
+ cursor: default;
+}
+.btn-static:active{
+ -moz-box-shadow: inset 0 0 0px white;
+ -webkit-box-shadow: inset 0 0 0px white;
+ box-shadow: inset 0 0 0px white;
+}
diff --git a/modules-available/locationinfo/templates/ajax-config-location.html b/modules-available/locationinfo/templates/ajax-config-location.html
index b42ff98d..102a6ea4 100644
--- a/modules-available/locationinfo/templates/ajax-config-location.html
+++ b/modules-available/locationinfo/templates/ajax-config-location.html
@@ -110,9 +110,9 @@
</select>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_serverTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_serverTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
<div class="row">
@@ -124,9 +124,9 @@
</div>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_recursiveSetTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_recursiveSetTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
<div class="row">
@@ -137,9 +137,9 @@
<input class="form-control" name="serverlocationid" id="serverlocationid" value="{{serverlocationid}}">
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_roomIdTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_roomIdTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
@@ -170,7 +170,7 @@
setTimepicker($('#settings-outer').find('.timepicker2'));
- $('a.helptext').tooltip();
+ $('p.helptext').tooltip();
$('#new-openingtime').click(function (e) {
e.preventDefault();
diff --git a/modules-available/locationinfo/templates/ajax-config-server.html b/modules-available/locationinfo/templates/ajax-config-server.html
index 940bc55a..8c2cb3ba 100644
--- a/modules-available/locationinfo/templates/ajax-config-server.html
+++ b/modules-available/locationinfo/templates/ajax-config-server.html
@@ -12,9 +12,9 @@
form="form-{{currentbackend}}">
</div>
<div class="col-md-2">
- <a class="btn btn-default" title="{{lang_nameTooltip}}">
+ <p class="btn btn-static" title="{{lang_nameTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -34,9 +34,9 @@
</select>
</div>
<div class="col-md-2">
- <a class="btn btn-default" id="help-type" title="{{lang_typeTooltip}}">
+ <p class="btn btn-static" id="help-type" title="{{lang_typeTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -92,7 +92,7 @@
currentBackend = value;
}
- $('a.btn[title]').tooltip();
+ $('p.btn[title]').tooltip();
$('#myModalSubmitButton').attr('form', 'form-' + currentBackend);
$('.settings-bs-switch').bootstrapSwitch({size:'small'});
diff --git a/modules-available/locationinfo/templates/frontend-default.html b/modules-available/locationinfo/templates/frontend-default.html
index e457f68d..cbb765d0 100755
--- a/modules-available/locationinfo/templates/frontend-default.html
+++ b/modules-available/locationinfo/templates/frontend-default.html
@@ -327,6 +327,7 @@ optional:
.wc-scrollable-grid {
transition: height 500ms;
background: rgba(0, 0, 0, 0);
+ overflow-y: hidden !important;
}
.wc-grid-timeslot-header,
@@ -351,6 +352,7 @@ optional:
<span data-tag="room">{{lang_room}}</span>
<span data-tag="closed">{{lang_closed}}</span>
<span data-tag="free">{{lang_free}}</span>
+ <span data-tag="for">{{lang_for}}</span>
<span data-tag="shortSun">{{lang_shortSun}}</span>
<span data-tag="shortMon">{{lang_shortMon}}</span>
<span data-tag="shortTue">{{lang_shortTue}}</span>
@@ -369,7 +371,6 @@ optional:
</div>
</body>
-<!--suppress RedundantIfStatementJS -->
<script type="text/javascript">
var rooms = {};
var lastRoomUpdate = 0;
@@ -619,6 +620,15 @@ optional:
generateProgressBar();
}
+ // Manually initialize mode 2, as initRoomLayout isn't called for this mode
+ if (room.config.mode === 2) {
+ var date = MyDate();
+ var now = date.getTime();
+ queryCalendars();
+ queryRooms();
+ lastCalendarUpdate = now;
+ lastRoomUpdate = now;
+ }
mainUpdateLoop();
setInterval(mainUpdateLoop, 10000);
setInterval(updateHeaders, globalConfig.eco ? 10000 : 1000);
@@ -736,7 +746,7 @@ optional:
timeslotHeight: 30,
daysToShow: daysToShow,
height: function () {
- if (room.config.mode === 1 && room.config.vertical && (!room.timetable || !room.timetable.length)) return 20;
+ // if (room.config.mode === 1 && room.config.vertical && (!room.timetable || !room.timetable.length)) return 20;
var height = $(window).height();
if (roomIds.length === 4) {
height /= 2;
@@ -771,7 +781,9 @@ optional:
timeSeparator: " - ",
startOnFirstDayOfWeek: false,
displayFreeBusys: true,
- defaultFreeBusy: {free: false}
+ defaultFreeBusy: {free: false},
+ allowCalEventOverlap: true,
+ overlapEventsSeparate: true
});
}
@@ -919,7 +931,7 @@ optional:
const SEVEN_DAYS = 7 * 86400 * 1000;
/**
- * applays new calendar data to the calendar plugin and also saves it to the room object
+ * applies new calendar data to the calendar plugin and also saves it to the room object
* @param {Array} json Calendar data
* @param room Room Object
*/
@@ -946,9 +958,18 @@ optional:
console.log('Notice: Calendar has no current events for ' + room.name);
}
try {
+ for (var i = json.length - 1; i > 0; i--) {
+ // if title, start and end are the same, "merge" two events by removing one of them
+ if (json[i].title === json[i-1].title && json[i].start === json[i-1].start && json[i].end === json[i-1].end) {
+ json.splice(i, 1);
+ }
+ }
room.timetable = json;
+ for (var property in room.timetable) {
+ room.timetable[property].start = cleanDate(room.timetable[property].start);
+ room.timetable[property].end = cleanDate(room.timetable[property].end);
+ }
if (room.config.mode !== 3) {
- // TODO: Check if they're the same
var cal = room.$.calendar;
cal.weekCalendar('option', 'data', {events: json});
cal.weekCalendar("refresh");
@@ -968,6 +989,27 @@ optional:
}
}
+ function cleanDate(d) {
+ if (typeof d === 'string') {
+ // if is numeric
+ if (!isNaN(Number(d))) {
+ return cleanDate(parseInt(d, 10));
+ }
+
+ // this is a human readable date
+ if (d[d.length - 1] !== 'Z') d += 'Z';
+ var o = new Date(d);
+ o.setTime(o.getTime() + (o.getTimezoneOffset() * 60 * 1000));
+ return o;
+ }
+
+ if (typeof d === 'number') {
+ return new Date(d);
+ }
+
+ return d;
+ }
+
/**
* scales calendar, called once on create and on window resize
* @param room Room Object
@@ -983,7 +1025,7 @@ optional:
if (room.config.scaledaysauto) {
var result = ($cal.weekCalendar("option", "daysToShow") * columnWidth) / 130;
- result = parseInt(Math.min(Math.max(Math.abs(result), 1), 7));
+ result = Math.min(Math.max(Math.abs(result), 1), 7);
if (result !== $cal.weekCalendar("option", "daysToShow")) {
$cal.weekCalendar("option", "daysToShow", result);
columnWidth = $cal.find(".wc-day-1").width();
@@ -1107,14 +1149,13 @@ optional:
/**
* Sets the free PCs number in the right corner and updates the square color accordingly
* @param room Room
- * @param seats Number of free PC's in the room
*/
function SetFreeSeats(room) {
- room.$.seatsCounter.text(room.freePcs >= 0 ? room.freePcs : '');
+ // if room has no allowed value, set text in the box to -
+ room.$.seatsCounter.text(room.freePcs >= 0 ? room.freePcs : '\u2014');
+ room.$.seatsCounter.data('state', JSON.stringify(room.state));
if (room.freePcs > 0 && room.state && room.state.free) {
- room.$.seatsBackground.css('background-color', '#250');
- } else if (room.freePcs === -1) {
- room.$.seatsBackground.css('background-color', 'red');
+ room.$.seatsBackground.css('background-color', '#250');
} else {
room.$.seatsBackground.css('background-color', 'red');
}
@@ -1134,26 +1175,23 @@ optional:
var seats = room.freePcs;
if (tmp.state === 'closed' || tmp.state === 'CalendarEvent' || tmp.state === 'Free') {
newTime = GetTimeDiferenceAsString(tmp.end, MyDate(), globalConfig);
- } else if (!same) {
- newTime = '';
}
if (tmp.state === "closed") {
if (!same) newText = t("closed");
} else if (tmp.state === "CalendarEvent") {
if (!same) newText = tmp.title;
- seats = -1;
- } else if (tmp.state === "Free") {
- if (!same) newText = t("free");
- } else if (tmp.state === "FreeNoEnd") {
+ // whilst event is running set freePcs to -, hopefully not breaking anything else with this
+ room.freePcs = "-";
+ } else if (tmp.state === "Free" || tmp.state === "FreeNoEnd") {
if (!same) newText = t("free");
}
if (newText !== false) {
room.$.currentEvent.text(newText);
}
if (newTime !== false) {
- room.$.currentRemain.text(newTime);
+ room.$.currentRemain.text(t("for") + " " +newTime);
}
- if (room.lastFreeSeats !== seats) {
+ if (room.lastFreeSeats !== seats || !same) {
SetFreeSeats(room);
room.lastFreeSeats = seats;
}
@@ -1167,11 +1205,10 @@ optional:
function ComputeCurrentState(room) {
if (!IsOpen(MyDate(), room)) {
room.state = {state: "closed", end: GetNextOpening(room), title: "", next: ""};
-
return;
}
- var closing = GetNextClosing(room);
+ var closing = GetNextClosing(room);
var event = getNextEvent(room.timetable);
// no event and no closing
@@ -1224,7 +1261,7 @@ optional:
console.log('getNextEvent called with something not array: ' + typeof(calEvents));
return null;
}
- var event;
+ var event = null;
var now = MyDate();
for (var i = 0; i < calEvents.length; i++) {
//event is now active
@@ -1489,8 +1526,14 @@ optional:
for (var i = 0; i < update.length; i++) {
var $div = $("#pc_" + room.id + "_" + update[i].id);
// Pc free
- if (update[i].pcState === "IDLE" || update[i].pcState === "OFFLINE" || update[i].pcState === "STANDBY") {
- freePcs++;
+ if (room.config.roomplanner === true) {
+ if ((update[i].pcState === "IDLE" || update[i].pcState === "OFFLINE" || update[i].pcState === "STANDBY") && !isNaN(update[i].x) && !isNaN(update[i].y)) {
+ freePcs++;
+ }
+ } else {
+ if ((update[i].pcState === "IDLE" || update[i].pcState === "OFFLINE" || update[i].pcState === "STANDBY")) {
+ freePcs++;
+ }
}
$div.removeClass('BROKEN OFFLINE IDLE OCCUPIED STANDBY'.replace(update[i].pcState, '')).addClass(update[i].pcState);
@@ -1586,7 +1629,7 @@ optional:
/**
* Function for translation
- * @param toTranslate key which we wan't to translate
+ * @param toTranslate key which we want to translate
* @returns r translated string
*/
function t(toTranslate) {
diff --git a/modules-available/locationinfo/templates/frontend-summary.html b/modules-available/locationinfo/templates/frontend-summary.html
index 4105dd16..ae089da5 100644
--- a/modules-available/locationinfo/templates/frontend-summary.html
+++ b/modules-available/locationinfo/templates/frontend-summary.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html lang="de">
+<html lang="{{language}}">
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8">
<head>
<script type='text/javascript' src='{{dirprefix}}script/jquery.js'></script>
@@ -63,7 +63,7 @@
}
.pc-idle, .pc-occupied, .pc-offline, .pc-broken, .pc-standby {
- padding: 2px 1px;
+ padding: 2px 0px;
text-align: center;
font-size: 90%;
font-weight: 800;
@@ -82,7 +82,8 @@
}
.pc-offline {
- background-color: darkgrey;
+ background-color: black;
+ color: white;
}
.pc-standby {
@@ -91,8 +92,7 @@
.pc-broken {
- background-color: black;
- color: white;
+ background-color: darkgrey;
border-radius: 0px 3px 3px 0px;
}
@@ -108,6 +108,10 @@
border-radius: 1px;
}
+ #i18n {
+ display: none;
+ }
+
</style>
<script type='text/javascript'>
@@ -116,6 +120,7 @@
var startdate;
var roomidsString = "";
var config = {{{config}}};
+ var lastPanelUpdate = 0;
$(document).ready(function () {
init();
@@ -139,6 +144,7 @@
SetUpDate(time);
generateLayout(config.tree);
update();
+ setInterval(update, 10000);
}
function SetUpDate(d) {
@@ -165,7 +171,7 @@
*/
function generateObject(json, myParent, outermost) {
var obj;
- if (!json.children || json.children.length == 0) {
+ if (!json.children || json.children.length === 0) {
obj = generateChild(myParent, json.locationid, json.locationname, outermost);
} else {
obj = generateParent(myParent, json.locationid, json.locationname, outermost);
@@ -178,59 +184,24 @@
}
/**
- * Helper function to generate id string used in query functions
- * @param list A string, wicht contains ids or not(for now)
- * @param id An ID which should be added to the list
+ * Main Update loop, this loop runs every 10 seconds
*/
- function addIdToUpdateList(list, id) {
- if (list == "") {
- list += id;
- } else {
- list += ("," + id);
- }
- return list;
- }
-
-
- const ROOMUPDATE_MS = 2*60*1000;
- const CALUPDATE_MS = 20*60*1000;
- var timeout = null;
-
function update() {
- var calendarUpdateIds = "";
- var rommUpdateIds = "";
- var count = 0;
- var nextUpdate = 15000;
- var property;
- // TODO: Only query a few rooms is not possible with the new api stuff ...
- for (property in rooms) {
- if (rooms[property].lastCalendarUpdate === null || rooms[property].lastCalendarUpdate + CALUPDATE_MS < MyDate().getTime()) {
- // TODO: NOT NECESSARY ANYMORE?!
- calendarUpdateIds = addIdToUpdateList(calendarUpdateIds, rooms[property].id);
- count++;
- rooms[property].lastCalendarUpdate = MyDate().getTime();
- }
- if (rooms[property].lastRoomUpdate === null || rooms[property].lastRoomUpdate + ROOMUPDATE_MS < MyDate().getTime()) {
- // TODO: NOT NECESSARY ANYMORE?!
- rommUpdateIds = addIdToUpdateList(rommUpdateIds, rooms[property].id);
- count++;
- rooms[property].lastRoomUpdate = MyDate().getTime();
- }
- // TODO if (count > 7) break;
- }
- if (calendarUpdateIds !== "") {
- queryCalendars();
- nextUpdate = 1000;
- }
- if (rommUpdateIds !== "") {
+ var date = MyDate();
+ var now = date.getTime();
+ if (lastPanelUpdate + (config.panelupdate * 1000) < now) {
+ // Set Roomupdate Interval has passed, update.
queryRooms();
- nextUpdate = 1000;
- }
- if (nextUpdate !== 1000) {
+ queryCalendars();
+ lastPanelUpdate = now;
+ for (var property in rooms) {
+ rooms[property].lastCalendarUpdate = now;
+ rooms[property].lastRoomUpdate = now;
+ }
+ } else {
+ // Set Roomupdate Interval has NOT passed, check if panel was changed since last call and reload if true.
queryPanelChange();
}
- clearTimeout(timeout);
- setTimeout(update, nextUpdate);
}
function cleanDate(d) {
@@ -283,7 +254,6 @@
cache: false,
timeout: 30000,
success: function (result) {
- var l = result.length;
if (result[0] == null) {
console.log("Error: Backend reported null back for RoomUpdate, this might happend if the room isn't" +
"configurated.");
@@ -309,17 +279,16 @@
var state = room.getState();
if (state.state == "CalendarEvent") {
- updateCourseText(room.id, state.titel);
+ updateCourseText(room.id, state.title);
updateCoursTimer(room.id, GetTimeDiferenceAsString(state.end, MyDate()));
} else if (state.state == "Free") {
- updateCourseText(room.id, "Frei");
+ updateCourseText(room.id, t("free"));
updateCoursTimer(room.id, GetTimeDiferenceAsString(state.end, MyDate()));
} else if (state.state == "FreeNoEnd") {
- updateCourseText(room.id, "Frei");
+ updateCourseText(room.id, t("free"));
updateCoursTimer(room.id, "");
- }
- else if (state.state == "closed") {
- updateCourseText(room.id, "Geschlossen");
+ } else if (state.state == "closed") {
+ updateCourseText(room.id, t("closed"));
updateCoursTimer(room.id, "");
}
}
@@ -331,7 +300,7 @@
function updatePcStates(json) {
var l = json.length;
for (var i = 0; i < l; i++) {
- updateRoomUsage(json[i].id, json[i].idle, json[i].occupied, json[i].offline, json[i].broken, json[i].standby)
+ updateRoomUsage(json[i].id, json[i].idle, json[i].occupied, json[i].offline, json[i].broken, json[i].standby);
}
}
@@ -428,109 +397,86 @@
/**
* computes state of a room, states are:
- * closed, FreeNoEnd, Free, ClaendarEvent.
- * @param Room Object
+ * closed, FreeNoEnd, Free, CalendarEvent.
+ * @param room Object
*/
function ComputeCurrentState(room) {
- if (room.lastRoomUpdate === null) {
- room.state = {state: 'unknown'};
+ if (!IsOpen(MyDate(), room)) {
+ room.state = {state: "closed", end: GetNextOpening(room), title: "", next: ""};
return;
}
- if (!IsOpenNow(room)) {
- room.state = {state: "closed", end: GetNextOpening(room), titel: "", next: ""};
- return;
- }
- var closing = GetNextClosing(room);
+ console.log("Timetable", room.id, room.timetable);
+ var closing = GetNextClosing(room);
var event = getNextEvent(room.timetable);
+
+ console.log("Event", room.id, event);
+
// no event and no closing
- if (closing == null && event == null) {
- room.state = {state: "FreeNoEnd", end: "", titel: "", next: ""};
+ if (!closing && !event) {
+ room.state = {state: "FreeNoEnd", end: "", title: "", next: "", free: true};
return;
}
// no event so closing is next
- if (event == null) {
- room.state = {state: "Free", end: closing, titel: "", next: "closing"};
+ if (!event) {
+ room.state = {state: "Free", end: closing, title: "", next: "closing", free: true};
return;
}
// event is at the moment
- if ((closing == null || event.start.getTime() < closing.getTime()) && event.start.getTime() < new MyDate()) {
- room.state = {state: "CalendarEvent", end: event.end, titel: event.title, next: ""};
+ if ((!closing || event.start.getTime() < closing.getTime()) && event.start.getTime() < MyDate()) {
+ room.state = {
+ state: "CalendarEvent",
+ end: event.end,
+ title: event.title,
+ next: ""
+ };
+ console.log("CalendarEvent", room.id, room.state);
return;
}
// no closing so event is next
- if (closing == null) {
- room.state = {state: "Free", end: event.start, titel: "", next: "event"};
+ if (!closing) {
+ room.state = {state: "Free", end: event.start, title: "", next: "event", free: true};
return;
}
// event sooner then closing
if (event.start.getTime() < closing) {
- room.state = {state: "Free", end: event.start, titel: "", next: "event"};
- } else if (event.start.getTime() > closing) {
- room.state = {state: "Free", end: closing, titel: "", next: "closing"};
- }
- }
-
- /**
- * checks if a room is open
- * @param room Room object
- * @returns bool for open or not
- */
- function IsOpenNow(room) {
- var now = new MyDate();
- if (room.openingTimes == null) {
-
- // changes from falls needs testing
- return true;
+ room.state = {state: "Free", end: event.start, title: "", next: "event", free: true};
+ } else {
+ room.state = {state: "Free", end: closing, title: "", next: "closing", free: true};
}
- var tmp = room.openingTimes[now.getDay()];
- if (tmp == null) {
- return false;
- }
- for (var i = 0; i < tmp.length; i++) {
- var openDate = new MyDate();
- openDate.setHours(tmp[i].HourOpen);
- openDate.setMinutes(tmp[i].MinutesOpen);
- var closeDate = new MyDate();
- closeDate.setHours(tmp[i].HourClose);
- closeDate.setMinutes(tmp[i].MinutesClose);
- if (openDate < now && closeDate > now) {
- return true;
- }
- }
- return false;
}
/**
* returns next event from a given json of events
- * @param json Json which contains the calendar data.
- * @returns event next Carlendar Event
+ * @param calEvents Json which contains the calendar data.
+ * @returns event next Calendar Event
*/
- function getNextEvent(json) {
- if (json == null) {
- return;
- }
- var event;
- var now = new MyDate();
- for (var i = 0; i < json.length; i++) {
+ function getNextEvent(calEvents) {
+ if (!calEvents) return null;
+ if (calEvents.constructor !== Array) {
+ console.log('getNextEvent called with something not array: ' + typeof(calEvents));
+ return null;
+ }
+ var event = null;
+ var now = MyDate();
+ for (var i = 0; i < calEvents.length; i++) {
//event is now active
- if (json[i].start.getTime() < now.getTime() && json[i].end.getTime() > now.getTime()) {
- return json[i];
+ if (calEvents[i].start.getTime() < now.getTime() && calEvents[i].end.getTime() > now.getTime()) {
+ return calEvents[i];
}
//first element to consider
- if (event == null) {
- if (json[i].start.getTime() > now.getTime()) {
- event = json[i];
+ if (!event) {
+ if (calEvents[i].start.getTime() > now.getTime()) {
+ event = calEvents[i];
}
- }
- if (json[i].start.getTime() > now.getTime() && event.start.getTime() > json[i].start.getTime()) {
- event = json[i];
+ } else if (calEvents[i].start.getTime() > now.getTime() && event.start.getTime() > calEvents[i].start.getTime()) {
+ event = calEvents[i];
}
}
return event;
@@ -658,7 +604,11 @@
// TODO: Add seconds again with a better update rate.
var time_split = time.split(":");
if (time != "") {
- $("#div_Time_" + id).text(time_split[0] + ":" + time_split[1]);
+ if (time_split[0] > 0) {
+ $("#div_Time_" + id).text(t("for") + " " + time_split[0] + "h " + time_split[1]+"min");
+ } else {
+ $("#div_Time_" + id).text(t("for") + " " + time_split[1]+"min");
+ }
} else {
$("#div_Time_" + id).text(time);
}
@@ -791,9 +741,44 @@
})
}
+ /**
+ * Function for translation
+ * @param toTranslate key which we want to translate
+ * @returns r translated string
+ */
+ function t(toTranslate) {
+ if (tCache[toTranslate])
+ return tCache[toTranslate];
+ var r = $('#i18n').find('[data-tag="' + toTranslate + '"]');
+ return tCache[toTranslate] = (r.length === 0 ? toTranslate : r.text());
+ }
+ var tCache = {};
+
</script>
</head>
<body>
<div id="main"></div>
+
+<div id="i18n">
+ <span data-tag="room">{{lang_room}}</span>
+ <span data-tag="closed">{{lang_closed}}</span>
+ <span data-tag="free">{{lang_free}}</span>
+ <span data-tag="for">{{lang_for}}</span>
+ <span data-tag="shortSun">{{lang_shortSun}}</span>
+ <span data-tag="shortMon">{{lang_shortMon}}</span>
+ <span data-tag="shortTue">{{lang_shortTue}}</span>
+ <span data-tag="shortWed">{{lang_shortWed}}</span>
+ <span data-tag="shortThu">{{lang_shortThu}}</span>
+ <span data-tag="shortFri">{{lang_shortFri}}</span>
+ <span data-tag="shortSat">{{lang_shortSat}}</span>
+ <span data-tag="longSun">{{lang_longSun}}</span>
+ <span data-tag="longMon">{{lang_longMon}}</span>
+ <span data-tag="longTue">{{lang_longTue}}</span>
+ <span data-tag="longWed">{{lang_longWed}}</span>
+ <span data-tag="longThu">{{lang_longThu}}</span>
+ <span data-tag="longFri">{{lang_longFri}}</span>
+ <span data-tag="longSat">{{lang_longSat}}</span>
+ <span data-tag="to">{{lang_to}}</span>
+</div>
</body>
</html>
diff --git a/modules-available/locationinfo/templates/page-config-panel-default.html b/modules-available/locationinfo/templates/page-config-panel-default.html
index b55e3d4d..116c2e11 100644
--- a/modules-available/locationinfo/templates/page-config-panel-default.html
+++ b/modules-available/locationinfo/templates/page-config-panel-default.html
@@ -28,9 +28,9 @@
<input class="form-control" name="name" id="panel-title" type="text" value="{{panelname}}">
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_displayNameTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_displayNameTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -48,9 +48,9 @@
</select>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_languageTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_languageTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -69,9 +69,9 @@
</select>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_modeTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_modeTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -85,9 +85,9 @@
<input id="input-eco" type="checkbox" name="eco" {{eco_checked}}>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_ecoTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_ecoTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -101,9 +101,25 @@
<input id="input-prettytime" type="checkbox" name="prettytime" {{prettytime_checked}}>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_prettytimeTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_prettytimeTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
+ </div>
+ </div>
+ </div>
+
+ <div class="list-group-item">
+ <div class="row">
+ <div class="col-sm-3">
+ <label for="input-roomplanner">{{lang_useRoomplanner}}</label>
+ </div>
+ <div class="col-sm-7">
+ <input id="input-roomplanner" type="checkbox" name="roomplanner" {{roomplanner_checked}}>
+ </div>
+ <div class="col-sm-2">
+ <p class="btn btn-static helptext" title="{{lang_roomplannerTooltip}}">
+ <span class="glyphicon glyphicon-question-sign"></span>
+ </p>
</div>
</div>
</div>
@@ -128,9 +144,9 @@
max="1440" value="{{calupdate}}" required>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_calupdateTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_calupdateTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -145,9 +161,9 @@
max="86400" value="{{roomupdate}}" required>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_roomupdateTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_roomupdateTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -177,9 +193,9 @@
<input id="input-vertical" type="checkbox" name="vertical" {{vertical_checked}}>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_verticalTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_verticalTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -193,9 +209,9 @@
<input id="scaledaysauto" type="checkbox" name="scaledaysauto" {{scaledaysauto_checked}}>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_autoscaleTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_autoscaleTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -217,9 +233,9 @@
</select>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_daysToShowTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_daysToShowTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -238,9 +254,9 @@
</select>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_rotationTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_rotationTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -255,9 +271,9 @@
<input id="input-scale" name="scale" type="range" step="1" min="10" max="90" value="{{scale}}">
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_scaleTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_scaleTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -272,9 +288,9 @@
<input id="input-switchtime" name="switchtime" type="range" step="1" min="1" max="120" value="{{switchtime}}">
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_switchTimeTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_switchTimeTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -293,7 +309,7 @@
</ul>
<div class="dropdown pull-right">
- <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown">
+ <button id="addLocDdBtn" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-plus"></span>
</button>
<ul class="dropdown-menu" id="location-list">
@@ -309,8 +325,10 @@
</div>
</div>
- <button type="submit" class="btn btn-primary">{{lang_save}}</button>
- <a href="?do=locationinfo&amp;show=panels" class="btn btn-default">{{lang_cancel}}</a>
+ <div class="text-right">
+ <a href="?do=locationinfo&amp;show=panels" class="btn btn-default">{{lang_cancel}}</a>
+ <button type="submit" class="btn btn-primary">{{lang_save}}</button>
+ </div>
</form>
<div class="modal fade" id="no-locations-message" tabindex="-1" role="dialog">
@@ -336,9 +354,10 @@ document.addEventListener("DOMContentLoaded", function () {
var $selLocs = $('#selected-locations');
var $locList = $('#location-list');
var $locInput = $('#locationids');
+ var $addLocDbBtn = $('#addLocDdBtn');
// Initialize fancy tooltips
- $('a.helptext').tooltip();
+ $('p.helptext').tooltip();
// Add listener to range sliders so their label can be updated
$('input[type="range"]').change(function () {
$(this).siblings().find('.range-display').text($(this).val());
@@ -372,6 +391,7 @@ document.addEventListener("DOMContentLoaded", function () {
// Adding/removing locations
$locList.find('a').click(function(ev) {
ev.preventDefault();
+ ev.stopPropagation();
var $this = $(this);
var name = $this.find('.name').text();
var id = $this.data('lid');
@@ -388,13 +408,24 @@ document.addEventListener("DOMContentLoaded", function () {
function addLocation(id, name) {
$selLocs.find('li[data-lid="' + id + '"]').remove();
- var delButton = $('<button class="btn btn-danger btn-xs" type="button">').append($('<span class="glyphicon glyphicon-remove">')).click(delParent);
- $selLocs.append($('<li>').attr('data-lid', id).text(name).prepend(delButton));
+ var delButton = $('<button style="margin-right: 5px;" class="btn btn-danger btn-xs" type="button">').append($('<span class="glyphicon glyphicon-remove">')).click(delParent);
+ $selLocs.append($('<li style="margin-top: 5px;">').attr('data-lid', id).text(name).prepend(delButton));
+
+ if ($selLocs.find('li').length >= 4) {
+ $addLocDbBtn.prop("disabled",true);
+ var $addLocBtnParent = $addLocDbBtn.parent();
+ if ($addLocBtnParent.hasClass('open')) {
+ $addLocBtnParent.removeClass('open');
+ }
+ }
}
function delParent() {
$(this).parent().remove();
serializeLocs();
+ if ($selLocs.find('li').length < 4) {
+ $addLocDbBtn.prop("disabled",false);
+ }
}
function serializeLocs() {
diff --git a/modules-available/locationinfo/templates/page-config-panel-summary.html b/modules-available/locationinfo/templates/page-config-panel-summary.html
index 2a968fc2..a77719b8 100644
--- a/modules-available/locationinfo/templates/page-config-panel-summary.html
+++ b/modules-available/locationinfo/templates/page-config-panel-summary.html
@@ -28,9 +28,9 @@
<input class="form-control" name="name" id="panel-title" type="text" value="{{panelname}}">
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_displayNameTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_displayNameTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -48,9 +48,9 @@
</select>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_languageTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_languageTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -64,9 +64,25 @@
<input id="input-eco" type="checkbox" name="eco" {{eco_checked}}>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_ecoTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_ecoTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
+ </div>
+ </div>
+ </div>
+
+ <div class="list-group-item">
+ <div class="row">
+ <div class="col-sm-3">
+ <label for="input-roomplanner">{{lang_useRoomplanner}}</label>
+ </div>
+ <div class="col-sm-7">
+ <input id="input-roomplanner" type="checkbox" name="roomplanner" {{roomplanner_checked}}>
+ </div>
+ <div class="col-sm-2">
+ <p class="btn btn-static helptext" title="{{lang_roomplannerTooltip}}">
+ <span class="glyphicon glyphicon-question-sign"></span>
+ </p>
</div>
</div>
</div>
@@ -91,6 +107,34 @@
</div>
</div>
</div>
+
+ <div class="col-md-6">
+ <div class="panel panel-default">
+ <div class="panel-heading">{{lang_updateRates}}</div>
+ <div class="panel-body">
+ <div class="list-group">
+
+ <div class="list-group-item">
+ <div class="row">
+ <div class="col-sm-3">
+ <label for="form-panelupdate">{{lang_panel}}</label>
+ </div>
+ <div class="col-sm-7">
+ <input class="form-control" name="panelupdate" type="number" min="15" id="form-panelupdate"
+ max="86400" value="{{panelupdate}}" required>
+ </div>
+ <div class="col-sm-2">
+ <p class="btn btn-static helptext" title="{{lang_panelupdateTooltip}}">
+ <span class="glyphicon glyphicon-question-sign"></span>
+ </p>
+ </div>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ </div>
</div>
<div class="modify-inputs">
@@ -101,7 +145,7 @@
<div class="panel-heading">{{lang_locations}}</div>
<div class="panel-body">
<input type="hidden" name="locationids" value="{{locationids}}" id="locationids">
- <p>{{lang_fourLocsHint}}</p>
+ <p>{{lang_locsHint}}</p>
<ul id="selected-locations" class="list-unstyled">
</ul>
@@ -122,8 +166,10 @@
</div>
</div>
- <button type="submit" class="btn btn-primary">{{lang_save}}</button>
- <a href="?do=locationinfo&amp;show=panels" class="btn btn-default">{{lang_cancel}}</a>
+ <div class="text-right">
+ <a href="?do=locationinfo&amp;show=panels" class="btn btn-default">{{lang_cancel}}</a>
+ <button type="submit" class="btn btn-primary">{{lang_save}}</button>
+ </div>
</form>
<div class="modal fade" id="no-locations-message" tabindex="-1" role="dialog">
@@ -151,7 +197,7 @@ document.addEventListener("DOMContentLoaded", function () {
var $locInput = $('#locationids');
// Initialize fancy tooltips
- $('a.helptext').tooltip();
+ $('p.helptext').tooltip();
// Add listener to range sliders so their label can be updated
$('input[type="range"]').change(function () {
$(this).siblings().find('.range-display').text($(this).val());
@@ -171,6 +217,7 @@ document.addEventListener("DOMContentLoaded", function () {
// Adding/removing locations
$locList.find('a').click(function(ev) {
ev.preventDefault();
+ ev.stopPropagation();
var $this = $(this);
var name = $this.find('.name').text();
var id = $this.data('lid');
@@ -187,8 +234,8 @@ document.addEventListener("DOMContentLoaded", function () {
function addLocation(id, name) {
$selLocs.find('li[data-lid="' + id + '"]').remove();
- var delButton = $('<button class="btn btn-danger btn-xs" type="button">').append($('<span class="glyphicon glyphicon-remove">')).click(delParent);
- $selLocs.append($('<li>').attr('data-lid', id).text(name).prepend(delButton));
+ var delButton = $('<button style="margin-right: 5px;" class="btn btn-danger btn-xs" type="button">').append($('<span class="glyphicon glyphicon-remove">')).click(delParent);
+ $selLocs.append($('<li style="margin-top: 5px;">').attr('data-lid', id).text(name).prepend(delButton));
}
function delParent() {
diff --git a/modules-available/locationinfo/templates/page-config-panel-url.html b/modules-available/locationinfo/templates/page-config-panel-url.html
index cca81509..1187c19f 100644
--- a/modules-available/locationinfo/templates/page-config-panel-url.html
+++ b/modules-available/locationinfo/templates/page-config-panel-url.html
@@ -25,9 +25,9 @@
<input class="form-control" name="name" id="panel-title" type="text" value="{{panelname}}">
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_displayNameTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_displayNameTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -42,9 +42,9 @@
placeholder="http://www.bwlehrpool.de/" pattern=".*://.*" required>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_urlTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_urlTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -61,9 +61,9 @@
</div>
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_ignoreSslTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_ignoreSslTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -77,9 +77,9 @@
<input class="form-control" id="input-reload" type="number" min="0" max="999" name="reloadminutes" pattern="\d*" value="{{reloadminutes}}">
</div>
<div class="col-sm-2">
- <a class="btn btn-default helptext" title="{{lang_reloadIntervalTooltip}}">
+ <p class="btn btn-static helptext" title="{{lang_reloadIntervalTooltip}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
</div>
</div>
</div>
@@ -87,14 +87,17 @@
</div>
</div>
</div>
-
- <button type="submit" class="btn btn-primary">{{lang_save}}</button>
- <a href="?do=locationinfo&amp;show=panels" class="btn btn-default">{{lang_cancel}}</a>
+ <div class="text-right">
+ <a href="?do=locationinfo&amp;show=panels" class="btn btn-default">{{lang_cancel}}</a>
+ <button type="submit" class="btn btn-primary">{{lang_save}}</button>
+ </div>
</form>
<script type="text/javascript"><!--
document.addEventListener("DOMContentLoaded", function () {
+ // Initialize fancy tooltips
+ $('p.helptext').tooltip();
});
diff --git a/modules-available/locationinfo/templates/page-locations.html b/modules-available/locationinfo/templates/page-locations.html
index b30ef2ed..c79cdfe8 100644
--- a/modules-available/locationinfo/templates/page-locations.html
+++ b/modules-available/locationinfo/templates/page-locations.html
@@ -8,7 +8,7 @@
<th>{{lang_locationName}}</th>
<th>{{lang_backend}}</th>
<th>{{lang_lastCalendarUpdate}}</th>
- <th>{{lang_openingtimes}}</th>
+ <th class="text-center slx-smallcol">{{lang_openingtimes}}</th>
</tr>
</thead>
@@ -17,20 +17,24 @@
<tr>
<td>
<div style="display:inline-block;width:{{depth}}em"></div>
+ {{#allowed}}
<a href="#" class="loc-name {{^depth}}slx-bold{{/depth}}" data-locationid="{{locationid}}">
+ {{/allowed}}
{{locationname}}
+ {{#allowed}}
<span class="glyphicon glyphicon-edit"></span>
</a>
+ {{/allowed}}
</td>
<td {{#backendMissing}}class="text-danger"{{/backendMissing}}>
{{backend}}
</td>
- <td>
+ <td class="text-center">
{{#backend}}
{{lastCalendarUpdate}}
{{/backend}}
</td>
- <td>
+ <td class="text-center">
<span class="glyphicon glyphicon-{{openingGlyph}}"></span>
</td>
</tr>
@@ -49,8 +53,8 @@
<div class="modal-header"><h2 id="location-modal-header"></h2></div>
<div class="modal-body"></div>
<div class="modal-footer">
+ <a class="btn btn-default" data-dismiss="modal">{{lang_close}}</a>
<button type="submit" class="btn btn-primary">{{lang_save}}</button>
- <a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a>
</div>
</form>
</div>
@@ -103,4 +107,4 @@ document.addEventListener("DOMContentLoaded", function () {
$('#settings-form').submit(submitLocationSettings);
});
-//--></script> \ No newline at end of file
+//--></script>
diff --git a/modules-available/locationinfo/templates/page-panels.html b/modules-available/locationinfo/templates/page-panels.html
index e17b6584..b30e7c87 100644
--- a/modules-available/locationinfo/templates/page-panels.html
+++ b/modules-available/locationinfo/templates/page-panels.html
@@ -9,16 +9,13 @@
<th>{{lang_panelType}}</th>
<th>{{lang_locations}}</th>
{{#hasRunmode}}
- <th class="slx-smallcol">{{lang_runmodeTHead}}</th>
+ <th class="text-center slx-smallcol">{{lang_runmodeTHead}}</th>
{{/hasRunmode}}
- <th class="slx-smallcol">{{lang_edit}}</th>
- <th class="slx-smallcol">{{lang_delete}}</th>
+ <th class="text-center slx-smallcol">{{lang_edit}}</th>
+ <th class="text-center slx-smallcol">{{lang_delete}}</th>
</tr>
</thead>
<tbody>
- <form method="post" action="?do=locationinfo" onsubmit="return confirm('{{lang_areYouSure}}')">
- <input type="hidden" name="token" value="{{token}}">
- <input type="hidden" name="action" value="deletePanel">
{{#panels}}
<tr>
<td>
@@ -33,26 +30,27 @@
{{#locationurl}}</a>{{/locationurl}}
</td>
{{#hasRunmode}}
- <td>
- <a class="btn btn-default btn-xs" href="?do=runmode&amp;module=locationinfo&amp;modeid={{paneluuid}}&amp;redirect=?do=locationinfo">
+ <td class="text-center" style="vertical-align: middle">
+ <a class="btn btn-default btn-xs {{runmode_disabled}}"
+ href="?do=runmode&amp;module=locationinfo&amp;modeid={{paneluuid}}&amp;redirect=?do=locationinfo">
<span class="glyphicon glyphicon-edit"></span>
</a>
{{assignedMachineCount}}
</td>
{{/hasRunmode}}
- <td>
- <a class="btn btn-default btn-xs" href="?do=locationinfo&amp;show=edit-panel&amp;uuid={{paneluuid}}">
+ <td class="text-center" style="vertical-align: middle">
+ <a class="btn btn-default btn-xs {{edit_disabled}}"
+ href="?do=locationinfo&amp;show=edit-panel&amp;uuid={{paneluuid}}">
<span class="glyphicon glyphicon-cog"></span>
</a>
</td>
- <td>
- <button type="submit" name="uuid" value="{{paneluuid}}" class="btn btn-danger btn-xs">
+ <td class="text-center" style="vertical-align: middle">
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="deletePanel('{{paneluuid}}')" {{edit_disabled}}>
<span class="glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
{{/panels}}
- </form>
</tbody>
</table>
@@ -69,4 +67,33 @@
<span class="glyphicon glyphicon-plus"></span>
{{lang_urlPanel}}
</a>
-</div> \ No newline at end of file
+</div>
+
+<form method="post" action="?do=locationinfo">
+<input type="hidden" name="token" value="{{token}}">
+
+<div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_deleteConfirmation}}</p>
+ </div>
+ <div class="modal-footer">
+ <input type="hidden" id="delete-panel-id" name="uuid" value="">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="deletePanel" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+</div>
+</form>
+
+<script>
+ function deletePanel(panelid) {
+ $("#delete-panel-id").val(panelid);
+ }
+</script> \ No newline at end of file
diff --git a/modules-available/locationinfo/templates/page-servers.html b/modules-available/locationinfo/templates/page-servers.html
index eefb1ed5..46a148ce 100644
--- a/modules-available/locationinfo/templates/page-servers.html
+++ b/modules-available/locationinfo/templates/page-servers.html
@@ -2,49 +2,67 @@
<p>{{lang_serverTableHints}}</p>
-<table class="table table-hover">
- <thead>
- <tr>
- <th width="1">{{lang_serverType}}</th>
- <th>{{lang_locationName}}</th>
- <th width="1"></th>
- <th width="1"></th>
- </tr>
- </thead>
- <tbody>
- {{#serverlist}}
- <form method="post" action="?do=locationinfo">
- <input type="hidden" name="token" value="{{token}}">
- <input type="hidden" name="serverid" value="{{serverid}}">
+<form method="post" action="?do=locationinfo">
+ <table class="table table-hover">
+ <thead>
<tr>
- <td nowrap>{{typename}}</td>
- <td nowrap>{{servername}}</td>
-
- <td align="center" nowrap>
- <button class="btn btn-xs {{^autherror}}btn-default{{/autherror}}{{#autherror}}btn-danger{{/autherror}}"
- data-server-edit="{{serverid}}" {{disabled}} type="button">
- <span class="glyphicon glyphicon-cog"></span>
- {{lang_edit}}
- </button>
- <button class="btn btn-xs btn-primary server-check" {{disabled}} name="action" value="checkConnection"
- type="submit">
- <span class="glyphicon glyphicon-refresh"></span>
- {{lang_checkConnection}}
- </button>
- </td>
- <td align="center" nowrap>
- <button class="btn btn-xs btn-danger server-delete" type="submit" name="action" value="deleteServer">
- <span class="glyphicon glyphicon-trash"></span>
- {{lang_delete}}
- </button>
- </td>
+ <th class="text-center slx-smallcol">{{lang_serverType}}</th>
+ <th>{{lang_locationName}}</th>
+ <th class="text-center slx-smallcol">{{lang_edit}}</th>
+ <th class="text-center slx-smallcol">{{lang_checkConnection}}</th>
+ <th class="text-center slx-smallcol">{{lang_delete}}</th>
</tr>
- </form>
- {{/serverlist}}
- </tbody>
-</table>
+ </thead>
+ <tbody>
+ {{#serverlist}}
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="serverid" value="{{serverid}}">
+ <tr>
+ <td nowrap>{{typename}}</td>
+ <td nowrap>{{servername}}</td>
+
+ <td class="text-center">
+ <button class="btn btn-xs {{^autherror}}btn-default{{/autherror}}{{#autherror}}btn-danger{{/autherror}}"
+ data-server-edit="{{serverid}}" {{disabled}} {{perms.backend.edit.disabled}} type="button">
+ <span class="glyphicon glyphicon-cog"></span>
+ </button>
+ </td>
+ <td class="text-center">
+ <button class="btn btn-xs btn-primary server-check" {{disabled}} {{perms.backend.check.disabled}}
+ name="action" value="checkConnection" type="submit">
+ <span class="glyphicon glyphicon-refresh"></span>
+ </button>
+ </td>
+ <td class="text-center">
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" {{perms.backend.edit.disabled}}>
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ </td>
+ </tr>
+ {{/serverlist}}
+ </tbody>
+ </table>
+
+ <div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_deleteConfirmation}}</p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="deleteServer" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
-<div>
+<div class="text-right">
<button class="btn btn-sm btn-success" id="addServerButton" onclick="addServer()">
<span class="glyphicon glyphicon-plus"></span>
{{lang_addServer}}
@@ -53,17 +71,14 @@
<div class="modal fade" id="myModal" tabindex="-1" role="dialog">
<div class="modal-dialog">
-
<div class="modal-content">
<div class="modal-header" id="myModalHeader"></div>
<div class="modal-body" id="myModalBody"></div>
<div class="modal-footer">
+ <a class="btn btn-default" data-dismiss="modal">{{lang_close}}</a>
<button type="submit" id="myModalSubmitButton" class="btn btn-primary" form="">{{lang_save}}</button>
-
- <a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a>
</div>
</div>
-
</div>
</div>
diff --git a/modules-available/locationinfo/templates/page-tabs.html b/modules-available/locationinfo/templates/page-tabs.html
index ed3f01fd..743297e7 100644
--- a/modules-available/locationinfo/templates/page-tabs.html
+++ b/modules-available/locationinfo/templates/page-tabs.html
@@ -1,6 +1,6 @@
<ul class="nav nav-tabs">
- <li class="{{class-}}"><a href="?do=locationinfo">{{lang_panels}}</a></li>
- <li class="{{class-locations}}"><a href="?do=locationinfo&amp;show=locations">{{lang_locationSettings}}</a></li>
- <li class="{{class-backends}}"><a href="?do=locationinfo&amp;show=backends">{{lang_backends}}</a></li>
+ <li class="{{class-panels}} {{perms.panel.list.disabled}}"><a href="?do=locationinfo&show=panels">{{lang_panels}}</a></li>
+ <li class="{{class-locations}} {{perms.location.disabled}}"><a href="?do=locationinfo&amp;show=locations">{{lang_locationSettings}}</a></li>
+ <li class="{{class-backends}} {{perms.backend.disabled}}"><a href="?do=locationinfo&amp;show=backends">{{lang_backends}}</a></li>
</ul>
<br> \ No newline at end of file
diff --git a/modules-available/locationinfo/templates/server-prop-bool.html b/modules-available/locationinfo/templates/server-prop-bool.html
index f430d02c..bd9dcc64 100644
--- a/modules-available/locationinfo/templates/server-prop-bool.html
+++ b/modules-available/locationinfo/templates/server-prop-bool.html
@@ -7,10 +7,10 @@
</div>
<div class="col-md-2">
{{#helptext}}
- <a class="btn btn-default" title="{{helptext}}">
+ <p class="btn btn-static" title="{{helptext}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
{{/helptext}}
</div>
</div>
-</div> \ No newline at end of file
+</div>
diff --git a/modules-available/locationinfo/templates/server-prop-dropdown.html b/modules-available/locationinfo/templates/server-prop-dropdown.html
index 80667766..d1351551 100644
--- a/modules-available/locationinfo/templates/server-prop-dropdown.html
+++ b/modules-available/locationinfo/templates/server-prop-dropdown.html
@@ -10,10 +10,10 @@
</div>
<div class="col-md-2">
{{#helptext}}
- <a class="btn btn-default" title="{{helptext}}">
+ <p class="btn btn-static" title="{{helptext}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
{{/helptext}}
</div>
</div>
-</div> \ No newline at end of file
+</div>
diff --git a/modules-available/locationinfo/templates/server-prop-generic.html b/modules-available/locationinfo/templates/server-prop-generic.html
index 9e94c23d..23ff1e4e 100644
--- a/modules-available/locationinfo/templates/server-prop-generic.html
+++ b/modules-available/locationinfo/templates/server-prop-generic.html
@@ -7,10 +7,10 @@
</div>
<div class="col-md-2">
{{#helptext}}
- <a class="btn btn-default" title="{{helptext}}">
+ <p class="btn btn-static" title="{{helptext}}">
<span class="glyphicon glyphicon-question-sign"></span>
- </a>
+ </p>
{{/helptext}}
</div>
</div>
-</div> \ No newline at end of file
+</div>
diff --git a/modules-available/locations/config.json b/modules-available/locations/config.json
index 706412d0..110f8b67 100644
--- a/modules-available/locations/config.json
+++ b/modules-available/locations/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.content"
-}
+ "category": "main.content"
+} \ No newline at end of file
diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php
index 0576e660..8db0c5f3 100644
--- a/modules-available/locations/inc/location.inc.php
+++ b/modules-available/locations/inc/location.inc.php
@@ -251,7 +251,7 @@ class Location
{
$ids = array();
foreach ($tree as $node) {
- $ids[] = $node['locationid'];
+ $ids[] = (int)$node['locationid'];
if (!empty($node['children'])) {
$ids = array_merge($ids, self::extractIds($node['children']));
}
@@ -429,7 +429,7 @@ class Location
foreach ($self as $entry) {
if (!isset($locs[$entry]))
continue;
- $overlapSelf[]['locationname'] = $locs[$entry['locationid']]['locationname'];
+ $overlapSelf[]['locationname'] = $locs[$entry]['locationname'];
}
}
if ($overlapOther) {
diff --git a/modules-available/locations/lang/de/messages.json b/modules-available/locations/lang/de/messages.json
index 95002ee7..6b682c7e 100644
--- a/modules-available/locations/lang/de/messages.json
+++ b/modules-available/locations/lang/de/messages.json
@@ -3,6 +3,7 @@
"invalid-location-id": "Ung\u00fcltige Orts-id: {{0}}",
"location-deleted": "Location wurde gel\u00f6scht (Locations: {{0}}, Subnets: {{1}})",
"location-updated": "Location {{0}} wurde aktualisiert",
+ "no-permission-location": "Keine Rechte f\u00fcr Ort {{0}}",
"parameter-missing": "Fehlender Parameter: {{0}}",
"subnets-created": "Subnetze angelegt: {{0}}",
"subnets-deleted": "Subnetze gel\u00f6scht: {{0}}",
diff --git a/modules-available/locations/lang/de/permissions.json b/modules-available/locations/lang/de/permissions.json
index 46dea864..8a9336b3 100644
--- a/modules-available/locations/lang/de/permissions.json
+++ b/modules-available/locations/lang/de/permissions.json
@@ -1,9 +1,9 @@
{
- "location.view": "Räume anschauen.",
- "location.edit": "Räume bearbeiten.",
- "location.add": "Räume hinzufügen.",
- "location.delete": "Räume löschen.",
- "subnet.edit": "Subnetze bearbeiten.",
- "subnet.add": "Subnetze hinzufügen.",
- "subnet.delete": "Subnetze löschen."
+ "location.add": "R\u00e4ume\/Orte hinzuf\u00fcgen.",
+ "location.delete": "R\u00e4ume\/Orte l\u00f6schen.",
+ "location.edit.name": "Orte umbenennen.",
+ "location.edit.parent": "Den \u00fcbergeordneten Ort eines Ortes \u00e4ndern.",
+ "location.edit.subnets": "Die IP-Ranges eines Ortes \u00e4ndern.",
+ "location.view": "R\u00e4ume anschauen.",
+ "subnets.edit": "Subnetze mittels der Subnetz\u00fcbersicht \u00e4ndern."
} \ No newline at end of file
diff --git a/modules-available/locations/lang/de/template-tags.json b/modules-available/locations/lang/de/template-tags.json
index 04d10d06..96273ce4 100644
--- a/modules-available/locations/lang/de/template-tags.json
+++ b/modules-available/locations/lang/de/template-tags.json
@@ -3,10 +3,11 @@
"lang_areYouSureNoUndo": "Sind Sie sicher? Diese Aktion kann nicht r\u00fcckg\u00e4ngig gemacht werden.",
"lang_assignSubnetExplanation": "Rechner, die in einen der hier aufgef\u00fchrten Adressbereiche fallen, werden diesem Ort zugeschrieben und erhalten damit z.B. f\u00fcr diesen Raum angepasste Veranstaltungslisten.",
"lang_assignedSubnets": "Zugeordnete Subnetze bzw. IP-Bereiche",
+ "lang_bootMenu": "Bootmen\u00fc",
"lang_deleteChildLocations": "Untergeordnete Orte ebenfalls l\u00f6schen",
"lang_deleteLocation": "Ort l\u00f6schen",
"lang_deleteSubnet": "Bereich l\u00f6schen",
- "lang_deleteSubnetWarning": "Alle zum L\u00f6schen markierten Subnetze werden gelöscht. Diese Aktion kann nicht r\u00fcckg\u00e4ngig gemacht werden.",
+ "lang_deleteSubnetWarning": "Alle zum L\u00f6schen markierten Subnetze werden gel\u00f6scht. Diese Aktion kann nicht r\u00fcckg\u00e4ngig gemacht werden.",
"lang_editConfigVariables": "Konfig.-Variablen",
"lang_editRoomplan": "Raumplan bearbeiten",
"lang_endAddress": "Endadresse",
@@ -22,10 +23,10 @@
"lang_machineLoad": "Besetzt",
"lang_matchingMachines": "Enthaltene Rechner",
"lang_name": "Name",
- "lang_noParent": "Kein \u00fcbergeordneter Ort",
"lang_overrideCount": "Angepasst",
"lang_parentLocation": "\u00dcbergeordneter Ort",
"lang_referencingLectures": "Veranstaltungen",
+ "lang_showRoomplan": "Raumplan anzeigen",
"lang_startAddress": "Startadresse",
"lang_subnet": "IP-Bereich",
"lang_sysConfig": "Lokalisierung",
diff --git a/modules-available/locations/lang/en/messages.json b/modules-available/locations/lang/en/messages.json
index fca00c7c..95788c47 100644
--- a/modules-available/locations/lang/en/messages.json
+++ b/modules-available/locations/lang/en/messages.json
@@ -3,6 +3,7 @@
"invalid-location-id": "Invalid location id: {{0}}",
"location-deleted": "Location has been deleted (locations: {{0}}, subnets: {{1}})",
"location-updated": "Location {{0}} has been updated",
+ "no-permission-location": "No permissions for location {{0}}",
"parameter-missing": "Missing parameter: {{0}}",
"subnets-created": "{{0}} subnet(s) created",
"subnets-deleted": "{{0}} subnet(s) deleted",
diff --git a/modules-available/locations/lang/en/permissions.json b/modules-available/locations/lang/en/permissions.json
index db0ac5f6..1d01a9d1 100644
--- a/modules-available/locations/lang/en/permissions.json
+++ b/modules-available/locations/lang/en/permissions.json
@@ -1,9 +1,9 @@
{
- "location.view": "View locations.",
- "location.edit": "Edit locations.",
- "location.add": "Add locations.",
- "location.delete": "Delete locations.",
- "subnet.edit": "Edit subnets.",
- "subnet.add": "Add subnets.",
- "subnet.delete": "Delete subnets."
+ "location.add": "Add locations.",
+ "location.delete": "Delete locations.",
+ "location.edit.name": "Rename locations.",
+ "location.edit.parent": "Change the parent location of a location.",
+ "location.edit.subnets": "Edit the IP ranges of a location.",
+ "location.view": "View locations.",
+ "subnets.edit": "Edit subnets via the subnet overview."
} \ No newline at end of file
diff --git a/modules-available/locations/lang/en/template-tags.json b/modules-available/locations/lang/en/template-tags.json
index ddb90f83..64211e27 100644
--- a/modules-available/locations/lang/en/template-tags.json
+++ b/modules-available/locations/lang/en/template-tags.json
@@ -3,6 +3,7 @@
"lang_areYouSureNoUndo": "Are you sure? This cannot be undone!",
"lang_assignSubnetExplanation": "Client machines which fall into an IP range listed below will be assigned to this location and will see an according lecture list (e.g. they will see lectures that are exclusively assigned to this location).",
"lang_assignedSubnets": "Assigned subnets \/ IP ranges",
+ "lang_bootMenu": "Boot menu",
"lang_deleteChildLocations": "Delete child locations aswell",
"lang_deleteLocation": "Delete location",
"lang_deleteSubnet": "Delete range",
@@ -22,14 +23,14 @@
"lang_machineLoad": "In use",
"lang_matchingMachines": "Matching clients",
"lang_name": "Name",
- "lang_noParent": "No parent",
"lang_overrideCount": "Overridden",
"lang_parentLocation": "Parent location",
"lang_referencingLectures": "Assigned Lectures",
+ "lang_showRoomplan": "Show room plan",
"lang_startAddress": "Start address",
"lang_subnet": "IP range",
"lang_sysConfig": "Localization\/Integration",
"lang_thisListByLocation": "Locations",
"lang_thisListBySubnet": "Subnets",
"lang_unassignedMachines": "Machines not matching any location"
-}
+} \ No newline at end of file
diff --git a/modules-available/locations/page.inc.php b/modules-available/locations/page.inc.php
index 0cfa5b90..2d8f5ff9 100644
--- a/modules-available/locations/page.inc.php
+++ b/modules-available/locations/page.inc.php
@@ -24,10 +24,14 @@ class Page_Locations extends Page
} elseif ($this->action === 'updatesubnets') {
$this->updateSubnets();
}
+ if (Request::isPost()) {
+ Util::redirect('?do=locations');
+ }
}
private function updateSubnets()
{
+ User::assertPermission('subnets.edit', NULL, '?do=locations');
$count = 0;
$starts = Request::post('startaddr', false);
$ends = Request::post('endaddr', false);
@@ -47,12 +51,6 @@ class Page_Locations extends Page
Message::addError('main.value-invalid', 'locationid', $loc);
continue;
}
-
- $oldLoc = Database::queryFirst("SELECT locationid FROM subnet WHERE subnetid = :subnetid", array("subnetid" => $subnetid))["locationid"];
- if (($loc == $oldLoc && !User::hasPermission("subnet.edit", $loc)) ||
- ($loc != $oldLoc && (!User::hasPermission("subnet.delete", $oldLoc) || !User::hasPermission("subnet.add", $loc))))
- continue;
-
$range = $this->rangeToLongVerbose($start, $end);
if ($range === false)
continue;
@@ -63,7 +61,7 @@ class Page_Locations extends Page
}
AutoLocation::rebuildAll();
Message::addSuccess('subnets-updated', $count);
- Util::redirect('?do=Locations&action=showsubnets');
+ Util::redirect('?do=Locations');
}
private function addLocations()
@@ -81,8 +79,10 @@ class Page_Locations extends Page
if (empty($name))
continue;
$parent = isset($parents[$idx]) ? (int)$parents[$idx] : 0;
- if (!User::hasPermission("location.add", $parent))
+ if (!User::hasPermission("location.add", $parent)) {
+ Message::addError('no-permission-location', isset($locs[$parent]) ? $locs[$parent]['locationname'] : $parent);
continue;
+ }
if ($parent !== 0) {
$ok = false;
foreach ($locs as $loc) {
@@ -123,24 +123,16 @@ class Page_Locations extends Page
$change = false;
// Delete location?
if ($locationId === $del) {
- if (!User::hasPermission("location.delete", $locationId)) {
- Message::addError('main.no-permission', 'locationid', $locationId);
- Util::redirect('?do=Locations');
- }
+ User::assertPermission("location.delete", $locationId, '?do=locations');
$this->deleteLocation($location);
$change = true;
}
// Update subnets
$change |= $this->updateLocationSubnets();
-
- if (User::hasPermission("subnet.add", $locationId)) {
- // Insert subnets
- $change |= $this->addNewLocationSubnets($location);
- }
- if (User::hasPermission("location.edit", $locationId)) {
- // Update location!
- $change |= $this->updateLocationData($location);
- }
+ // Insert subnets
+ $change |= $this->addNewLocationSubnets($location);
+ // Update location!
+ $change |= $this->updateLocationData($location);
if ($change) {
// In case subnets or tree layout changed, recalc this
@@ -176,13 +168,17 @@ class Page_Locations extends Page
$locationId = (int)$location['locationid'];
$newParent = Request::post('parentlocationid', false, 'integer');
$newName = Request::post('locationname', false, 'string');
- if ($newName === false || preg_match('/^\s*$/', $newName)) {
+ if (!User::hasPermission('location.edit.name', $locationId)) {
+ $newName = $location['locationname'];
+ } elseif ($newName === false || preg_match('/^\s*$/', $newName)) {
if ($newName !== false) {
Message::addWarning('main.value-invalid', 'location name', $newName);
}
$newName = $location['locationname'];
}
- if ($newParent === false) {
+ if ($newParent === false || !User::hasPermission('location.edit.parent', $locationId)
+ || !User::hasPermission('location.edit.parent', $newParent)
+ || !User::hasPermission('location.edit.*', $location['parentlocationid'])) {
$newParent = $location['parentlocationid'];
} else if ($newParent !== 0) {
$rows = Location::queryLocations();
@@ -213,13 +209,15 @@ class Page_Locations extends Page
private function updateLocationSubnets()
{
- $change = false;
-
$locationId = Request::post('locationid', false, 'integer');
+ if (!User::hasPermission('location.edit.subnets', $locationId))
+ return false;
+
+ $change = false;
// Deletion first
$dels = Request::post('deletesubnet', false);
- if (is_array($dels) && User::hasPermission("subnet.delete", $locationId)) {
+ if (is_array($dels)) {
$count = 0;
$stmt = Database::prepare('DELETE FROM subnet WHERE subnetid = :id');
foreach ($dels as $key => $value) {
@@ -234,8 +232,6 @@ class Page_Locations extends Page
$change = true;
}
}
- if (!User::hasPermission("subnet.edit", $locationId))
- return $change;
// Now actual updates
$starts = Request::post('startaddr', false);
@@ -267,8 +263,11 @@ class Page_Locations extends Page
private function addNewLocationSubnets($location)
{
- $change = false;
$locationId = (int)$location['locationid'];
+ if (!User::hasPermission('location.edit.subnets', $locationId))
+ return false;
+
+ $change = false;
$starts = Request::post('newstartaddr', false);
$ends = Request::post('newendaddr', false);
if (!is_array($starts) || !is_array($ends)) {
@@ -310,36 +309,32 @@ class Page_Locations extends Page
protected function doRender()
{
- $getAction = Request::get('action');
- if (empty($getAction)) {
- // Until we have a main landing page?
- Util::redirect('?do=Locations&action=showlocations');
+ $getAction = Request::get('action', false, 'string');
+ if ($getAction === false) {
+ if (User::hasPermission('location.view')) {
+ Util::redirect('?do=locations&action=showlocations');
+ } elseif (User::hasPermission('subnets.edit')) {
+ Util::redirect('?do=locations&action=showsubnets');
+ } else {
+ // Trigger permission denied by asserting non-existent permission
+ User::assertPermission('location.view');
+ }
}
if ($getAction === 'showsubnets') {
- $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet
- WHERE locationid IN (:locations) ORDER BY startaddr ASC",
- array("locations" => User::getAllowedLocations("location.view")));
- $allowedLocs = User::getAllowedLocations("subnet.add");
+ User::assertPermission('subnets.edit', NULL, '?do=locations');
+ $res = Database::simpleQuery("SELECT subnetid, startaddr, endaddr, locationid FROM subnet");
$rows = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$row['startaddr'] = long2ip($row['startaddr']);
$row['endaddr'] = long2ip($row['endaddr']);
$row['locations'] = Location::getLocations($row['locationid']);
-
- foreach ($row['locations'] as &$loc) {
- if (!(in_array($loc["locationid"], $allowedLocs) || $loc["locationid"] == $row['locationid'])) {
- $loc["disabled"] = "disabled";
- }
- }
-
- $row['editThisSubnetAllowed'] = User::hasPermission("subnet.edit", $row['locationid']);
- $row['deleteThisSubnetAllowed'] = User::hasPermission("subnet.delete", $row['locationid']);
$rows[] = $row;
}
-
- Render::addTemplate('subnets', array('list' => $rows, 'editSubnetAllowed' => User::hasPermission("subnet.edit")));
+ Render::addTemplate('subnets', array('list' => $rows));
} elseif ($getAction === 'showlocations') {
$this->showLocationList();
+ } else {
+ Util::redirect('?do=locations');
}
}
@@ -349,38 +344,88 @@ class Page_Locations extends Page
$overlapSelf = $overlapOther = true;
Location::getOverlappingSubnets($overlapSelf, $overlapOther);
//$locs = Location::getLocations(0, 0, false, true);
- $locs = Location::getLocationsAssoc();
+ $locationList = Location::getLocationsAssoc();
+ unset($locationList[0]);
// Statistics: Count machines for each subnet
$unassigned = false;
+ $unassignedLoad = 0;
+
+ // Filter view: Remove locations we can't reach at all, but show parents to locations
+ // we have permission to, so the tree doesn't look all weird
+ $visibleLocationIds = $allowedLocationIds = User::getAllowedLocations("location.view");
+ foreach ($allowedLocationIds as $lid) {
+ if (!isset($locationList[$lid]))
+ continue;
+ $visibleLocationIds = array_merge($visibleLocationIds, $locationList[$lid]['parents']);
+ }
+ $visibleLocationIds = array_unique($visibleLocationIds);
+ foreach (array_keys($locationList) as $lid) {
+ if (User::hasPermission('.baseconfig.view', $lid)) {
+ $visibleLocationIds[] = $lid;
+ } else {
+ $locationList[$lid]['havebaseconfig'] = false;
+ }
+ if (User::hasPermission('.sysconfig.config.view-list', $lid)) {
+ $visibleLocationIds[] = $lid;
+ } else {
+ $locationList[$lid]['havesysconfig'] = false;
+ }
+ if (User::hasPermission('.statistics.view.list', $lid)) {
+ $visibleLocationIds[] = $lid;
+ } else {
+ $locationList[$lid]['havestatistics'] = false;
+ }
+ if (User::hasPermission('.serversetup.ipxe.menu.assign', $lid)) {
+ $visibleLocationIds[] = $lid;
+ } else {
+ $locationList[$lid]['haveipxe'] = false;
+ }
+ if (!in_array($lid, $visibleLocationIds)) {
+ unset($locationList[$lid]);
+ } elseif (!in_array($lid, $allowedLocationIds)) {
+ $locationList[$lid]['show-only'] = true;
+ }
+ }
+
+ // Client statistics
if (Module::get('statistics') !== false) {
- $DL = time() - 605;
$unassigned = 0;
- $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt, Sum(If(lastseen > $DL AND logintime <> 0, 1, 0)) AS used
- FROM machine GROUP BY locationid");
+ $extra = '';
+ if (in_array(0, $allowedLocationIds)) {
+ $extra = ' OR locationid IS NULL';
+ }
+ $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt, Sum(If(state = 'OCCUPIED', 1, 0)) AS used
+ FROM machine WHERE (locationid IN (:allowedLocationIds) $extra) GROUP BY locationid", compact('allowedLocationIds'));
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $loc = (int)$row['locationid'];
- if (isset($locs[$loc])) {
- $locs[$loc]['clientCount'] = $row['cnt'];
- $locs[$loc]['clientLoad'] = round(100 * $row['used'] / $row['cnt']) . '%';
+ $locId = (int)$row['locationid'];
+ if (isset($locationList[$locId])) {
+ $locationList[$locId]['clientCount'] = $row['cnt'];
+ $locationList[$locId]['clientLoad'] = round(100 * $row['used'] / $row['cnt']) . ' %';
} else {
$unassigned += $row['cnt'];
+ $unassignedLoad += $row['used'];
}
}
unset($loc);
- foreach ($locs as &$loc) {
+ foreach ($locationList as &$loc) {
+ if (!in_array($loc['locationid'], $allowedLocationIds))
+ continue;
+ if (!isset($loc['clientCountSum'])) {
+ $loc['clientCountSum'] = 0;
+ }
if (!isset($loc['clientCount'])) {
$loc['clientCount'] = 0;
$loc['clientLoad'] = '0%';
}
- $loc['clientCountSum'] = $loc['clientCount'];
- }
- unset($loc);
- foreach ($locs as $loc) {
+ $loc['clientCountSum'] += $loc['clientCount'];
foreach ($loc['parents'] as $pid) {
- $locs[(int)$pid]['hasChild'] = true;
- $locs[(int)$pid]['clientCountSum'] += $loc['clientCount'];
+ if (!in_array($pid, $allowedLocationIds))
+ continue;
+ $locationList[(int)$pid]['hasChild'] = true;
+ $locationList[(int)$pid]['clientCountSum'] += $loc['clientCount'];
}
}
+ unset($loc);
}
// Show currently active sysconfig for each location
$defaultConfig = false;
@@ -390,85 +435,77 @@ class Page_Locations extends Page
if (strlen($conf['locs']) === 0)
continue;
$confLocs = explode(',', $conf['locs']);
- foreach ($confLocs as $loc) {
- settype($loc, 'int');
- if ($loc === 0) {
+ foreach ($confLocs as $locId) {
+ settype($locId, 'int');
+ if ($locId === 0) {
$defaultConfig = $conf['title'];
}
- if (!isset($locs[$loc]))
+ if (!isset($locationList[$locId]))
continue;
- $locs[$loc] += array('configName' => $conf['title'], 'configClass' => 'slx-bold');
+ $locationList[$locId] += array('configName' => $conf['title'], 'configClass' => 'slx-bold');
}
}
- $depth = array();
- foreach ($locs as &$loc) {
- $d = $loc['depth'];
- if (!isset($loc['configName'])) {
- // Has no explicit config assignment
- if ($d === 0) {
- $loc['configName'] = $defaultConfig;
- } else {
- $loc['configName'] = $depth[$d - 1];
- }
- $loc['configClass'] = 'gray';
- }
- $depth[$d] = $loc['configName'];
- unset($depth[$d + 1]);
- }
- unset($loc);
+ $this->propagateFields($locationList, $defaultConfig, 'configName', 'configClass');
}
// Count overridden config vars
if (Module::get('baseconfig') !== false) {
- $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt FROM `setting_location` GROUP BY locationid");
+ $res = Database::simpleQuery("SELECT locationid, Count(*) AS cnt FROM `setting_location`
+ WHERE locationid IN (:allowedLocationIds) GROUP BY locationid", compact('allowedLocationIds'));
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$lid = (int)$row['locationid'];
- if (isset($locs[$lid])) {
- $locs[$lid]['overriddenVars'] = $row['cnt'];
+ if (isset($locationList[$lid])) {
+ $locationList[$lid]['overriddenVars'] = $row['cnt'];
}
}
- }
-
- $allowedLocs = User::getAllowedLocations("location.view");
- $withParents = array();
- foreach ($allowedLocs as $loc) {
- $withParents = array_merge($withParents, Location::getLocationRootChain($loc));
- }
-
- foreach ($locs as $key => $loc) {
- if (!in_array($loc["locationid"], $withParents)) {
- unset($locs[$key]);
- } elseif (!in_array($loc["locationid"], $allowedLocs)) {
- $id = $locs[$key]["locationid"];
- $name = $locs[$key]["locationname"];
- $depth = $locs[$key]["depth"];
- $locs[$key] = array("locationid" => $id, "locationname" => $name, "depth" => $depth, "linkClass" => "not-allowed");
+ // Confusing because the count might be inaccurate within a branch
+ //$this->propagateFields($locationList, '', 'overriddenVars', 'overriddenClass');
+ }
+ // Show ipxe menu
+ if (Module::get('serversetup') !== false) {
+ $res = Database::simpleQuery("SELECT ml.locationid, m.title, ml.defaultentryid FROM serversetup_menu m
+ INNER JOIN serversetup_menu_location ml USING (menuid)
+ WHERE locationid IN (:allowedLocationIds) GROUP BY locationid", compact('allowedLocationIds'));
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $lid = (int)$row['locationid'];
+ if (isset($locationList[$lid])) {
+ if ($row['defaultentryid'] !== null) {
+ $row['title'] .= '(*)';
+ }
+ $locationList[$lid]['customMenu'] = $row['title'];
+ }
}
+ $this->propagateFields($locationList, '', 'customMenu', 'customMenuClass');
}
$addAllowedLocs = User::getAllowedLocations("location.add");
- $addAllowedLocs[] = 0;
$addAllowedList = Location::getLocations(0, 0, true);
foreach ($addAllowedList as &$loc) {
if (!in_array($loc["locationid"], $addAllowedLocs)) {
$loc["disabled"] = "disabled";
}
}
+ unset($loc);
// Output
- Render::addTemplate('locations', array(
- 'list' => array_values($locs),
+ $data = array(
+ 'list' => array_values($locationList),
'havestatistics' => Module::get('statistics') !== false,
'havebaseconfig' => Module::get('baseconfig') !== false,
'havesysconfig' => Module::get('sysconfig') !== false,
+ 'haveipxe' => Module::get('serversetup') !== false,
'overlapSelf' => $overlapSelf,
'overlapOther' => $overlapOther,
'haveOverlapSelf' => !empty($overlapSelf),
'haveOverlapOther' => !empty($overlapOther),
'unassignedCount' => $unassigned,
+ 'unassignedLoad' => round(($unassignedLoad / $unassigned) * 100) . ' %',
'defaultConfig' => $defaultConfig,
- 'addAllowed' => User::hasPermission("location.add"),
- 'addAllowedList' => array_values($addAllowedList)
- ));
+ 'addAllowedList' => array_values($addAllowedList),
+ );
+ // TODO: Buttons for config vars and sysconfig are currently always shown, as their availability
+ // depends on permissions in the according modules, not this one
+ Permission::addGlobalTags($data['perms'], NULL, ['subnets.edit', 'location.add']);
+ Render::addTemplate('locations', $data);
}
/*
@@ -491,9 +528,7 @@ class Page_Locations extends Page
{
$locationId = Request::any('locationid', 0, 'integer');
- if (!User::hasPermission("location.view", $locationId)) {
- die('Permission denied');
- }
+ User::assertPermission("location.view", $locationId);
$loc = Database::queryFirst('SELECT locationid, parentlocationid, locationname FROM location WHERE locationid = :lid',
array('lid' => $locationId));
@@ -516,11 +551,16 @@ class Page_Locations extends Page
'parents' => Location::getLocations($loc['parentlocationid'], $locationId, true)
);
- $allowedLocs = User::getAllowedLocations("location.edit");
- $allowedLocs[] = 0;
- foreach ($data['parents'] as &$parent) {
- if (!(in_array($parent["locationid"], $allowedLocs) || $parent["locationid"] == $loc['parentlocationid'])) {
- $parent["disabled"] = "disabled";
+ // Disable locations in the parent selector where the user cannot change to
+ if (!User::hasPermission('location.edit.*', $loc['parentlocationid'])
+ || !User::hasPermission('location.edit.parent', $locationId)) {
+ $allowedLocs = [];
+ } else {
+ $allowedLocs = User::getAllowedLocations("location.edit.*");
+ foreach ($data['parents'] as &$parent) {
+ if (!(in_array($parent["locationid"], $allowedLocs) || $parent["locationid"] == $loc['parentlocationid'])) {
+ $parent["disabled"] = "disabled";
+ }
}
}
@@ -534,19 +574,25 @@ class Page_Locations extends Page
// Get clients matching this location's subnet(s)
$count = $online = $used = 0;
if (Module::get('statistics') !== false) {
- $mres = Database::simpleQuery("SELECT lastseen, logintime FROM machine"
+ $mres = Database::simpleQuery("SELECT state FROM machine"
. " WHERE machine.locationid = :lid", array('lid' => $locationId));
- $DL = time() - 605;
while ($row = $mres->fetch(PDO::FETCH_ASSOC)) {
$count++;
- if ($row['lastseen'] > $DL) {
+ if ($row['state'] === 'IDLE') {
$online++;
- if ($row['logintime'] != 0) {
- $used++;
- }
+ }
+ if ($row['state'] === 'OCCUPIED') {
+ $online++;
+ $used++;
}
}
$data['haveStatistics'] = true;
+ // Link
+ if (User::hasPermission('.statistics.view.list')) {
+ $data['statsLink'] = 'list';
+ } elseif (User::hasPermission('.statistics.view.summary')) {
+ $data['statsLink'] = 'summary';
+ }
}
$data['machines'] = $count;
$data['machines_online'] = $online;
@@ -554,18 +600,13 @@ class Page_Locations extends Page
$data['used_percent'] = $count === 0 ? 0 : round(($used / $count) * 100);
- $data['havebaseconfig'] = Module::get('baseconfig') !== false;
- $data['havesysconfig'] = Module::get('sysconfig') !== false;
- $data['editAllowed'] = User::hasPermission("location.edit", $locationId);
- $data['deleteAllowed'] = User::hasPermission("location.delete", $locationId);
- $data['editSubnetAllowed'] = User::hasPermission("subnet.edit", $locationId);
- $data['deleteSubnetAllowed'] = User::hasPermission("subnet.delete", $locationId);
- $data['addSubnetAllowed'] = User::hasPermission("subnet.add", $locationId);
- $data['saveButton'] = $data['editAllowed'] || $data['editSubnetAllowed'] || $data['deleteSubnetAllowed'] || $data['addSubnetAllowed'];
+ Permission::addGlobalTags($data['perms'], $locationId, ['location.edit.name', 'location.edit.subnets', 'location.delete', '.roomplanner.edit'], 'save_button');
+ if (empty($allowedLocs)) {
+ $data['perms']['location']['edit']['parent']['disabled'] = 'disabled';
+ } else {
+ unset($data['perms']['save_button']);
+ }
- // echo '<pre>';
- // var_dump($data);
- // echo '</pre>';
echo Render::parse('location-subnets', $data);
}
@@ -605,4 +646,23 @@ class Page_Locations extends Page
return $result;
}
+ private function propagateFields(&$locationList, $defaultValue, $name, $class)
+ {
+ $depth = array();
+ foreach ($locationList as &$loc) {
+ $d = $loc['depth'];
+ if (!isset($loc[$name])) {
+ // Has no explicit config assignment
+ if ($d === 0) {
+ $loc[$name] = $defaultValue;
+ } else {
+ $loc[$name] = $depth[$d - 1];
+ }
+ $loc[$class] = 'gray';
+ }
+ $depth[$d] = $loc[$name];
+ unset($depth[$d + 1]);
+ }
+ }
+
}
diff --git a/modules-available/locations/permissions/permissions.json b/modules-available/locations/permissions/permissions.json
index 609a673a..18b24a73 100644
--- a/modules-available/locations/permissions/permissions.json
+++ b/modules-available/locations/permissions/permissions.json
@@ -1,9 +1,23 @@
-[
- "location.view",
- "location.edit",
- "location.add",
- "location.delete",
- "subnet.edit",
- "subnet.add",
- "subnet.delete"
-] \ No newline at end of file
+{
+ "location.add": {
+ "location-aware": true
+ },
+ "location.delete": {
+ "location-aware": true
+ },
+ "location.edit.name": {
+ "location-aware": true
+ },
+ "location.edit.subnets": {
+ "location-aware": true
+ },
+ "location.edit.parent": {
+ "location-aware": true
+ },
+ "location.view": {
+ "location-aware": true
+ },
+ "subnets.edit": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/locations/templates/location-subnets.html b/modules-available/locations/templates/location-subnets.html
index 2cc8e98b..69e369c2 100644
--- a/modules-available/locations/templates/location-subnets.html
+++ b/modules-available/locations/templates/location-subnets.html
@@ -8,17 +8,17 @@
<button type="submit" class="btn btn-primary">Save</button>
</div>
<div class="row">
- <div class="{{^editAllowed}}disabled{{/editAllowed}}">
+ <div>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon slx-ga">{{lang_name}}</span>
- <input class="form-control" type="text" name="locationname" value="{{locationname}}" pattern=".*\S.*">
+ <input {{perms.location.edit.name.disabled}} class="form-control" type="text" name="locationname" value="{{locationname}}" pattern=".*\S.*">
</div>
</div>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon slx-ga2">{{lang_parentLocation}}</span>
- <select class="form-control" name="parentlocationid">
+ <select class="form-control" name="parentlocationid" {{perms.location.edit.parent.disabled}}>
{{#parents}}
<option {{disabled}} value="{{locationid}}" {{#selected}}selected="selected"{{/selected}}>{{locationpad}} {{locationname}}</option>
{{/parents}}
@@ -40,11 +40,11 @@
{{#list}}
<tr class="cidrmagic">
<td>{{subnetid}}</td>
- <td class="{{^editSubnetAllowed}}disabled{{/editSubnetAllowed}}"><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
- <td class="{{^editSubnetAllowed}}disabled{{/editSubnetAllowed}}"><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
+ <td><input {{perms.location.edit.subnets.disabled}} class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
+ <td><input {{perms.location.edit.subnets.disabled}} class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"></td>
<td class="danger">
<div class="checkbox text-center" style="margin-left: 9px">
- <input {{^deleteSubnetAllowed}}disabled{{/deleteSubnetAllowed}} type="checkbox" name="deletesubnet[{{subnetid}}]" value="on">
+ <input {{perms.location.edit.subnets.disabled}} type="checkbox" name="deletesubnet[{{subnetid}}]" value="on">
<label class="text-left"></label>
</div>
</td>
@@ -52,7 +52,7 @@
{{/list}}
<tr id="loc-sub-{{locationid}}">
<td colspan="4">
- <button {{^addSubnetAllowed}}disabled{{/addSubnetAllowed}} class="btn btn-success btn-sm pull-right" type="button" onclick="slxAddSubnetRow(this, {{locationid}})" title="{{lang_addNewSubnet}}">
+ <button {{perms.location.edit.subnets.disabled}} class="btn btn-success btn-sm pull-right" type="button" onclick="slxAddSubnetRow(this, {{locationid}})" title="{{lang_addNewSubnet}}">
<span class="glyphicon glyphicon-plus"></span> {{lang_subnet}}
</button>
</td>
@@ -69,24 +69,30 @@
{{/haveDozmod}}
{{#haveStatistics}}
<div>
- <span class="slx-ga2">{{lang_matchingMachines}}:</span> <a href="?do=Statistics&amp;show=list&amp;filters=location={{locationid}}">{{machines}} / {{machines_online}} / {{machines_used}} ({{used_percent}}%)</a>
+ <span class="slx-ga2">{{lang_matchingMachines}}:</span>
+ {{#statsLink}}
+ <a href="?do=Statistics&amp;show={{statsLink}}&amp;filters=location={{locationid}}">
+ {{/statsLink}}
+ {{machines}} / {{machines_online}} / {{machines_used}} ({{used_percent}}%)
+ {{#statsLink}}
+ </a>
+ {{/statsLink}}
</div>
{{/haveStatistics}}
</div>
<div class="col-md-4 text-center">
- <div class="btn-group">
- {{#roomplanner}}
- <a class="btn btn-default" href="?do=roomplanner&amp;locationid={{locationid}}" target="_blank"
- onclick="window.open(this.href, '_blank', 'toolbar=0,scrollbars,resizable');return false">
- <span class="glyphicon glyphicon-move"></span> {{lang_editRoomplan}}
- </a>
- {{/roomplanner}}
- </div>
-
+ {{#roomplanner}}
+ <a class="btn btn-default" href="?do=roomplanner&amp;locationid={{locationid}}" target="_blank"
+ onclick="window.open(this.href, '_blank', 'toolbar=0,scrollbars,resizable');return false">
+ <span class="glyphicon glyphicon-move"></span>
+ {{^perms.roomplanner.edit.disabled}}{{lang_editRoomplan}}{{/perms.roomplanner.edit.disabled}}
+ {{#perms.roomplanner.edit.disabled}}{{lang_showRoomplan}}{{/perms.roomplanner.edit.disabled}}
+ </a>
+ {{/roomplanner}}
</div>
<div class="col-md-4 text-right">
- <button style="margin-right: 10px" {{^deleteAllowed}}disabled{{/deleteAllowed}} type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteLocationModal{{locationid}}"><span class="glyphicon glyphicon-trash"></span> {{lang_deleteLocation}}</button>
- <button onclick="deleteSubnetWarning('{{locationid}}')" {{^saveButton}}disabled{{/saveButton}} type="button" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button {{perms.location.delete.disabled}} type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteLocationModal{{locationid}}"><span class="glyphicon glyphicon-trash"></span> {{lang_deleteLocation}}</button>
+ <button onclick="deleteSubnetWarning('{{locationid}}')" {{perms.save_button.disabled}} type="button" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
</div>
diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html
index be3d5115..06d32020 100644
--- a/modules-available/locations/templates/locations.html
+++ b/modules-available/locations/templates/locations.html
@@ -1,7 +1,13 @@
<div>
<div class="btn-group pull-right">
- <a href="?do=Locations&amp;action=showlocations" class="btn btn-default active"><span class="glyphicon glyphicon-home"></span> {{lang_thisListByLocation}}</a>
- <a href="?do=Locations&amp;action=showsubnets" class="btn btn-default"><span class="glyphicon glyphicon-list-alt"></span> {{lang_thisListBySubnet}}</a>
+ <a href="?do=Locations&amp;action=showlocations" class="btn btn-default active">
+ <span class="glyphicon glyphicon-home"></span>
+ {{lang_thisListByLocation}}
+ </a>
+ <a href="?do=Locations&amp;action=showsubnets" class="btn btn-default {{perms.subnets.edit.disabled}}">
+ <span class="glyphicon glyphicon-list-alt"></span>
+ {{lang_thisListBySubnet}}
+ </a>
</div>
<h1>{{lang_locationsMainHeading}}</h1>
@@ -31,15 +37,25 @@
<th class="text-nowrap">
{{#havesysconfig}}{{lang_sysConfig}}{{/havesysconfig}}
</th>
+ <th class="text-nowrap">
+ {{#haveipxe}}{{lang_bootMenu}}{{/haveipxe}}
+ </th>
</tr>
{{#list}}
<tr>
<td>
<div style="display:inline-block;width:{{depth}}em"></div>
- <a href="#" class="{{linkClass}}" onclick="slxOpenLocation(this, {{locationid}}); return false">{{locationname}}{{^linkClass}} <b class="caret"></b>{{/linkClass}}</a>
+ {{#show-only}}
+ <span>{{locationname}}</span>
+ {{/show-only}}
+ {{^show-only}}
+ <a href="#" onclick="slxOpenLocation(this, {{locationid}}); return false">
+ {{locationname}}
+ <b class="caret"></b>
+ </a>
+ {{/show-only}}
</td>
<td class="text-nowrap" align="right">
- {{^linkClass}}
{{#havestatistics}}
<a href="?do=Statistics&amp;show=list&amp;filters=location={{locationid}}">&nbsp;{{clientCount}}&nbsp;</a>
<span style="display:inline-block;width:5ex">
@@ -48,17 +64,13 @@
{{/hasChild}}
</span>
{{/havestatistics}}
- {{/linkClass}}
</td>
<td class="text-nowrap" align="right">
- {{^linkClass}}
{{#havestatistics}}
{{clientLoad}}
{{/havestatistics}}
- {{/linkClass}}
</td>
- <td class="text-nowrap">
- {{^linkClass}}
+ <td class="text-nowrap {{overriddenClass}}">
{{#havebaseconfig}}
<div class="pull-right" style="z-index:-1">
<a class="btn btn-default btn-xs" href="?do=baseconfig&amp;module=locations&amp;locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a>
@@ -67,10 +79,8 @@
{{lang_overrideCount}}: {{overriddenVars}}&emsp;&emsp;
{{/overriddenVars}}
{{/havebaseconfig}}
- {{/linkClass}}
</td>
<td class="text-nowrap">
- {{^linkClass}}
{{#havesysconfig}}
<div class="pull-right">
<a class="btn btn-default btn-xs" href="?do=sysconfig&amp;locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a>
@@ -79,7 +89,16 @@
{{configName}}&emsp;&emsp;
</span>
{{/havesysconfig}}
- {{/linkClass}}
+ </td>
+ <td class="text-nowrap">
+ {{#haveipxe}}
+ <div class="pull-right">
+ <a class="btn btn-default btn-xs" href="?do=serversetup&amp;show=assignlocation&amp;locationid={{locationid}}"><span class="glyphicon glyphicon-edit"></span></a>
+ </div>
+ <span class="{{customMenuClass}}">
+ {{customMenu}}&emsp;&emsp;
+ </span>
+ {{/haveipxe}}
</td>
</tr>
{{/list}}
@@ -90,9 +109,10 @@
<a href="?do=Statistics&amp;show=list&amp;filters=location=0">
&nbsp;{{unassignedCount}}&nbsp;
</a>
+ <span style="display:inline-block;width:5ex"></span>
</td>
<td class="text-nowrap" align="right">
- {{clientLoad}}
+ {{unassignedLoad}}
</td>
<td></td>
<td>{{defaultConfig}}</td>
@@ -106,7 +126,7 @@
<tr id="lasttr">
<td width="60%">&emsp;</td>
<td class="text-right" colspan="2">
- <button {{^addAllowed}}disabled{{/addAllowed}} class="btn btn-success" type="button" onclick="slxAddLocationRow()">
+ <button {{perms.location.add.disabled}} class="btn btn-success" type="button" onclick="slxAddLocationRow()">
<span class="glyphicon glyphicon-plus"></span> {{lang_location}}
</button>
<button id="saveLocationRows" type="submit" class="btn btn-primary collapse">
@@ -163,7 +183,7 @@ function slxOpenLocation(e, lid) {
}
return;
}
- var td = $('<td>').attr('colspan', '5').css('padding', '0px 0px 12px');
+ var td = $('<td>').attr('colspan', '6').css('padding', '0px 0px 12px');
var tr = $('<tr>').attr('id', 'location-details-' + lid);
tr.append(td);
$(e).closest('tr').addClass('active slx-bold').after(tr);
diff --git a/modules-available/locations/templates/subnets.html b/modules-available/locations/templates/subnets.html
index cb7fb758..d027d800 100644
--- a/modules-available/locations/templates/subnets.html
+++ b/modules-available/locations/templates/subnets.html
@@ -17,9 +17,9 @@
{{#list}}
<tr class="cidrmagic">
<td>{{subnetid}}</td>
- <td class="{{^editThisSubnetAllowed}}disabled{{/editThisSubnetAllowed}}"><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}"></td>
- <td class="{{^editThisSubnetAllowed}}disabled{{/editThisSubnetAllowed}}"><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}"></td>
- <td class="{{^deleteThisSubnetAllowed}}disabled{{/deleteThisSubnetAllowed}}">
+ <td><input class="form-control cidrstart" type="text" name="startaddr[{{subnetid}}]" value="{{startaddr}}"></td>
+ <td><input class="form-control cidrend" type="text" name="endaddr[{{subnetid}}]" value="{{endaddr}}"></td>
+ <td>
<select class="form-control" name="location[{{subnetid}}]">
{{#locations}}
<option {{disabled}} value="{{locationid}}" {{#selected}}selected="selected"{{/selected}}>{{locationpad}} {{locationname}}</option>
@@ -30,7 +30,7 @@
{{/list}}
</table>
<div class="text-right" style="margin-bottom: 20px">
- <button {{^editSubnetAllowed}}disabled{{/editSubnetAllowed}} type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
</form>
</div>
diff --git a/modules-available/main/config.json b/modules-available/main/config.json
index 2c63c085..0637a088 100644
--- a/modules-available/main/config.json
+++ b/modules-available/main/config.json
@@ -1,2 +1 @@
-{
-}
+[] \ No newline at end of file
diff --git a/modules-available/main/install.inc.php b/modules-available/main/install.inc.php
index e364a905..ec8554fd 100644
--- a/modules-available/main/install.inc.php
+++ b/modules-available/main/install.inc.php
@@ -43,6 +43,7 @@ $res[] = tableCreate('user', "
`email` varchar(100) DEFAULT NULL,
`permissions` int(10) unsigned NOT NULL,
`lasteventid` int(10) unsigned NOT NULL DEFAULT '0',
+ `serverid` int(10) unsigned NULL DEFAULT NULL,
PRIMARY KEY (`userid`),
UNIQUE KEY `login` (`login`)
");
@@ -72,6 +73,20 @@ if (!tableHasColumn('callback', 'args')) {
Database::exec("ALTER TABLE `callback` ADD `args` TEXT NOT NULL DEFAULT ''");
}
+// #######################
+// ##### 2018-03-19
+// In preparation for LDAP/AD auth: Column to rembember origin server
+if (!tableHasColumn('user', 'serverid')) {
+ Database::exec("ALTER TABLE `user` ADD `serverid` int(10) unsigned NULL DEFAULT NULL");
+}
+
+// Make sure that if any users exist, one of the has UID=1, otherwise if the permission module is
+// used we'd lock out everyone
+$someUser = Database::queryFirst('SELECT userid FROM user ORDER BY userid ASC LIMIT 1');
+if ($someUser !== false && (int)$someUser['userid'] !== 1) {
+ Database::exec('UPDATE user SET userid = 1 WHERE userid = :oldid', ['oldid' => $someUser['userid']]);
+}
+
// Create response for browser
if (in_array(UPDATE_DONE, $res)) {
diff --git a/modules-available/main/lang/de/categories.json b/modules-available/main/lang/de/categories.json
index 71f149ec..587200ed 100644
--- a/modules-available/main/lang/de/categories.json
+++ b/modules-available/main/lang/de/categories.json
@@ -3,6 +3,5 @@
"content": "Inhalt",
"settings-client": "Einstellungen (Client)",
"settings-server": "Einstellungen (Server)",
- "status": "Status",
- "users": "Benutzer"
+ "status": "Status"
} \ No newline at end of file
diff --git a/modules-available/main/lang/de/template-tags.json b/modules-available/main/lang/de/template-tags.json
index 00e27502..327e19e4 100644
--- a/modules-available/main/lang/de/template-tags.json
+++ b/modules-available/main/lang/de/template-tags.json
@@ -1,7 +1,7 @@
{
"lang_browserTime": "Browser",
"lang_changePassword": "Passwort \u00e4ndern",
- "lang_clockDriftWarn": "Die Uhrzeit des Satelliten-Servers weicht von der Uhrzeit des lokalen Systems\/Browsers ab. Bitte stellen Sie sicher, dass die Uhrzeit des Servers korrekt ist, da sonst zeitabh\u00e4ngige Einstellungen und Aufgaben evtl. nicht korrekt durchgef\u00fchrt werden.",
+ "lang_clockDriftWarn": "Die Uhrzeit des Satellitenservers weicht von der Uhrzeit des lokalen Systems\/Browsers ab. Bitte stellen Sie sicher, dass die Uhrzeit des Servers korrekt ist, da sonst zeitabh\u00e4ngige Einstellungen und Aufgaben evtl. nicht korrekt durchgef\u00fchrt werden.",
"lang_goTo": "Gehe zu",
"lang_intro": "Dies ist die bwLehrpool Konfigurationsoberfl\u00e4che.",
"lang_introGuest": "Dies ist das Administrations-Interface der lokalen bwLehrpool-Installation. Bitte authentifizieren Sie sich, um Einstellungen vorzunehmen.",
@@ -11,7 +11,7 @@
"lang_login": "Anmelden",
"lang_logout": "Abmelden",
"lang_needsSetup": "Einrichtung unvollst\u00e4ndig",
- "lang_noExistingAccount": "Es existiert noch kein Administrator-Zugang f\u00fcr diesen Satelliten-Server.",
+ "lang_noExistingAccount": "Es existiert noch kein Administrator-Zugang f\u00fcr diesen Satellitenserver.",
"lang_register": "Registrieren",
"lang_serverTime": "Server",
"lang_toggleNavigation": "Navigation ein\/ausblenden",
diff --git a/modules-available/main/lang/en/categories.json b/modules-available/main/lang/en/categories.json
index 9dfa0404..f73f0a15 100644
--- a/modules-available/main/lang/en/categories.json
+++ b/modules-available/main/lang/en/categories.json
@@ -3,6 +3,5 @@
"content": "Content",
"settings-client": "Settings (Client)",
"settings-server": "Settings (Server)",
- "status": "Status",
- "users": "Users"
+ "status": "Status"
} \ No newline at end of file
diff --git a/modules-available/main/page.inc.php b/modules-available/main/page.inc.php
index 70296a59..baea8350 100644
--- a/modules-available/main/page.inc.php
+++ b/modules-available/main/page.inc.php
@@ -26,7 +26,10 @@ class Page_Main extends Page
// Warnings
$needSetup = false;
foreach (Hook::load('main-warning') as $hook) {
- include $hook->file;
+ if (Permission::moduleHasPermissions($hook->moduleId)
+ && User::hasPermission('.' . $hook->moduleId . '.*')) {
+ include $hook->file;
+ }
}
// Update warning state
diff --git a/modules-available/minilinux/config.json b/modules-available/minilinux/config.json
index 28d71577..6c7b7146 100644
--- a/modules-available/minilinux/config.json
+++ b/modules-available/minilinux/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.settings-client"
-}
+ "category": "main.settings-client"
+} \ No newline at end of file
diff --git a/modules-available/minilinux/lang/de/permissions.json b/modules-available/minilinux/lang/de/permissions.json
new file mode 100644
index 00000000..29012620
--- /dev/null
+++ b/modules-available/minilinux/lang/de/permissions.json
@@ -0,0 +1,4 @@
+{
+ "view": "Zeige Komponenten des Minilinux. Wird nicht benötigt, wenn Nutzer eine der anderen Rechte hat.",
+ "update": "Aktualisieren von Komponenten des Minilinux."
+} \ No newline at end of file
diff --git a/modules-available/minilinux/lang/de/template-tags.json b/modules-available/minilinux/lang/de/template-tags.json
index 18a8b7af..60a11db9 100644
--- a/modules-available/minilinux/lang/de/template-tags.json
+++ b/modules-available/minilinux/lang/de/template-tags.json
@@ -1,5 +1,4 @@
{
- "lang_uptodate": "Aktuell",
"lang_canUpdate1": "Mindestens eine Komponente von",
"lang_canUpdate2": "kann aktualisiert werden. F\u00fcr einen reibungslosen Betrieb wird empfohlen, alle Komponenten auf dem aktuellen Stand zu halten.",
"lang_configurationPackageNotFound": "Keine Konfigurationspakete gefunden!",
@@ -10,5 +9,7 @@
"lang_outdated": "Veraltet",
"lang_redownload": "Erneut herunterladen",
"lang_systemUpdated": "Das System ist auf dem aktuellen Stand.",
- "lang_update": "Aktualisieren"
+ "lang_update": "Aktualisieren",
+ "lang_updateAll": "Alle Module aktualisieren",
+ "lang_uptodate": "Aktuell"
} \ No newline at end of file
diff --git a/modules-available/minilinux/lang/en/permissions.json b/modules-available/minilinux/lang/en/permissions.json
new file mode 100644
index 00000000..b8389e62
--- /dev/null
+++ b/modules-available/minilinux/lang/en/permissions.json
@@ -0,0 +1,4 @@
+{
+ "view": "Show list of minilinux components. Not needed if User has any of the other permissions.",
+ "update": "Update minilinux components."
+} \ No newline at end of file
diff --git a/modules-available/minilinux/lang/en/template-tags.json b/modules-available/minilinux/lang/en/template-tags.json
index aef15c03..48ba0c15 100644
--- a/modules-available/minilinux/lang/en/template-tags.json
+++ b/modules-available/minilinux/lang/en/template-tags.json
@@ -1,5 +1,4 @@
{
- "lang_uptodate": "Up to date",
"lang_canUpdate1": "At least one component of",
"lang_canUpdate2": "Can be updated. For a smooth operation, it is recommended to keep all components up to date.",
"lang_configurationPackageNotFound": "Configuration package not found!",
@@ -10,5 +9,7 @@
"lang_outdated": "Outdated",
"lang_redownload": "Download again",
"lang_systemUpdated": "The system is up to date.",
- "lang_update": "Update"
+ "lang_update": "Update",
+ "lang_updateAll": "Update all modules",
+ "lang_uptodate": "Up to date"
} \ No newline at end of file
diff --git a/modules-available/minilinux/page.inc.php b/modules-available/minilinux/page.inc.php
index 98b0191d..2488b2dc 100644
--- a/modules-available/minilinux/page.inc.php
+++ b/modules-available/minilinux/page.inc.php
@@ -7,10 +7,12 @@ class Page_MiniLinux extends Page
{
User::load();
- if (!User::hasPermission('superadmin')) {
+ if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
+
+ User::assertPermission('view');
}
protected function doRender()
@@ -82,9 +84,11 @@ class Page_MiniLinux extends Page
$system['version'] = $selected['version'];
}
$data['versions'] = array_values($versionNumbers);
+ Permission::addGlobalTags($data['perms'], null, ['update']);
echo Render::parse('filelist', $data);
return;
case 'download':
+ User::assertPermission('update');
$id = Request::post('id');
$name = Request::post('name');
if (!$id || !$name || strpos("$id$name", '/') !== false) {
diff --git a/modules-available/minilinux/permissions/permissions.json b/modules-available/minilinux/permissions/permissions.json
new file mode 100644
index 00000000..b018ee72
--- /dev/null
+++ b/modules-available/minilinux/permissions/permissions.json
@@ -0,0 +1,8 @@
+{
+ "view": {
+ "location-aware": false
+ },
+ "update": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/minilinux/templates/filelist.html b/modules-available/minilinux/templates/filelist.html
index a1d0aa48..3c840c57 100644
--- a/modules-available/minilinux/templates/filelist.html
+++ b/modules-available/minilinux/templates/filelist.html
@@ -18,7 +18,7 @@
<p>
{{lang_canUpdate1}} <b>{{title}}</b> {{lang_canUpdate2}}
</p>
- <p><span class="btn btn-primary" onclick="slxUpdateAll(this, 'download-{{id}}')">{{lang_update}}</span></p>
+ <button {{perms.update.disabled}} class="btn btn-primary" onclick="slxUpdateAll(this, 'download-{{id}}')"><span class="glyphicon glyphicon-refresh"></span> {{lang_updateAll}}<span></span></button>
{{/systemChanged}}
{{^systemChanged}}
<p>{{lang_systemUpdated}}</p>
@@ -35,8 +35,8 @@
{{#fileChanged}}<span class="glyphicon glyphicon-exclamation-sign"></span> <b>{{lang_outdated}}</b>{{/fileChanged}}
</div>
<div class="col-xs-2">
- {{#fileChanged}}<span class="btn btn-primary btn-xs update-button" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')">{{lang_update}}</span>{{/fileChanged}}
- {{^fileChanged}}<span class="btn btn-default btn-xs" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')">{{lang_redownload}}</span>{{/fileChanged}}
+ {{#fileChanged}}<button {{perms.update.disabled}} class="btn btn-primary btn-xs update-button" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')"><span class="glyphicon glyphicon-refresh"></span> {{lang_update}}</button> {{/fileChanged}}
+ {{^fileChanged}}<button {{perms.update.disabled}} class="btn btn-default btn-xs" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')"><span class="glyphicon glyphicon-download-alt"></span> {{lang_redownload}}</button> {{/fileChanged}}
</div>
</div>
{{{download}}}
diff --git a/modules-available/news/config.json b/modules-available/news/config.json
index e076ea5c..23cd1443 100644
--- a/modules-available/news/config.json
+++ b/modules-available/news/config.json
@@ -1,4 +1,6 @@
{
- "category":"main.content",
- "dependencies": [ "js_stupidtable" ]
-}
+ "category": "main.content",
+ "dependencies": [
+ "js_stupidtable"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/news/lang/de/permissions.json b/modules-available/news/lang/de/permissions.json
index b2c6fb1b..888bb4a7 100644
--- a/modules-available/news/lang/de/permissions.json
+++ b/modules-available/news/lang/de/permissions.json
@@ -1,6 +1,7 @@
{
- "news.save": "Änderungen am News Text speichern.",
- "news.delete": "Alte News Texte löschen.",
- "help.save": "Änderungen am Hilfe Text speichern.",
- "help.delete": "Alte Hilfe Texte löschen."
+ "access-page": "Seite sehen.",
+ "help.delete": "Alte Hilfe Texte l\u00f6schen.",
+ "help.save": "\u00c4nderungen am Hilfe Text speichern.",
+ "news.delete": "Alte News Texte l\u00f6schen.",
+ "news.save": "\u00c4nderungen am News Text speichern."
} \ No newline at end of file
diff --git a/modules-available/news/lang/de/template-tags.json b/modules-available/news/lang/de/template-tags.json
index d8ad974f..c2b4bddc 100644
--- a/modules-available/news/lang/de/template-tags.json
+++ b/modules-available/news/lang/de/template-tags.json
@@ -1,4 +1,5 @@
{
+ "lang_confirmDelete": "Eintrag l\u00f6schen?",
"lang_content": "Inhalt",
"lang_date": "Datum",
"lang_editHelp": "Hilfe bearbeiten",
diff --git a/modules-available/news/lang/en/permissions.json b/modules-available/news/lang/en/permissions.json
index 90d07aef..37fc7a8e 100644
--- a/modules-available/news/lang/en/permissions.json
+++ b/modules-available/news/lang/en/permissions.json
@@ -1,6 +1,7 @@
{
- "news.save": "Save new news.",
- "news.delete": "Delete old news.",
- "help.save": "Save new help texts.",
- "help.delete": "Delete old help texts"
+ "access-page": "View page.",
+ "help.delete": "Delete old help texts.",
+ "help.save": "Save new help texts.",
+ "news.delete": "Delete old news.",
+ "news.save": "Save new news."
} \ No newline at end of file
diff --git a/modules-available/news/lang/en/template-tags.json b/modules-available/news/lang/en/template-tags.json
index 270fed44..d7567d99 100644
--- a/modules-available/news/lang/en/template-tags.json
+++ b/modules-available/news/lang/en/template-tags.json
@@ -1,4 +1,5 @@
{
+ "lang_confirmDelete": "Delete entry?",
"lang_content": "Content",
"lang_date": "Date",
"lang_editHelp": "Edit Help",
diff --git a/modules-available/news/page.inc.php b/modules-available/news/page.inc.php
index 399fc307..1e2e3eef 100644
--- a/modules-available/news/page.inc.php
+++ b/modules-available/news/page.inc.php
@@ -26,247 +26,239 @@ class Page_News extends Page
private $editHelp = false;
private $hasSummernote = false;
- /**
- * Implementation of the abstract doPreprocess function.
- *
- * Checks if the user is logged in and processes any
- * action if one was specified in the request.
- */
- protected function doPreprocess()
- {
- /* load summernote module if available */
- $this->hasSummernote = Module::isAvailable('summernote');
+ /**
+ * Implementation of the abstract doPreprocess function.
+ *
+ * Checks if the user is logged in and processes any
+ * action if one was specified in the request.
+ */
+ protected function doPreprocess()
+ {
+ /* load summernote module if available */
+ $this->hasSummernote = Module::isAvailable('summernote');
- // load user, we will need it later
- User::load();
- if (!User::isLoggedIn()) {
- Message::addError('main.no-permission');
- Util::redirect('?do=Main');
- }
+ // load user, we will need it later
+ User::load();
+ if (!User::isLoggedIn()) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
- // check which action we need to do
- $action = Request::any('action', 'show');
- if ($action === 'clear') {
- // clear news input fields
- // TODO: is this the right way?
- $this->newsId = false;
- $this->newsTitle = false;
- $this->newsContent = false;
- $this->newsDate = false;
- } elseif ($action === 'show') {
- /* load latest things */
- $this->loadLatest('help');
- $this->loadLatest('news');
+ // check which action we need to do
+ $action = Request::any('action', 'show');
+ if ($action === 'show') {
+ User::assertPermission('access-page');
+ /* load latest things */
+ $this->loadLatest('help');
+ $this->loadLatest('news');
- /* and also the news (or help) with the given id */
- if (!$this->loadNews(Request::any('newsid'))) {
- Message::addError('news-empty');
- }
+ /* and also the news (or help) with the given id */
+ if (!$this->loadNews(Request::any('newsid'))) {
+ Message::addError('news-empty');
+ }
- if (Request::any('editHelp')) {
- $this->editHelp = true;
- }
- } elseif ($action === 'save') {
- // save to DB
- /* find out whether it's news or help */
- $pageType = Request::post('news-type');
+ if (Request::any('editHelp')) {
+ $this->editHelp = true;
+ }
+ } elseif ($action === 'save') {
+ // save to DB
+ /* find out whether it's news or help */
+ $pageType = Request::post('news-type');
- if ($pageType == 'news') {
- if (User::hasPermission("news.save")) {
- if (!$this->saveNews()) {
- // re-set the fields we got
- Request::post('news-title') ? $this->newsTitle = Request::post('news-title') : $this->newsTitle = false;
- Request::post('news-content') ? $this->newsContent = Request::post('news-content') : $this->newsContent = false;
- } else {
- Message::addSuccess('news-save-success');
- $lastId = Database::lastInsertId();
- Util::redirect("?do=News&newsid=$lastId");
- }
- }
- } elseif ($pageType == 'help') {
- if (User::hasPermission("help.save")) {
- if ($this->saveHelp()) {
- Message::addSuccess('help-save-success');
- $lastId = Database::lastInsertId();
- Util::redirect("?do=News&newsid=$lastId");
- }
- }
- }
- } elseif ($action === 'delete') {
- // delete it
- $pageType = Request::post('news-type');
+ if ($pageType === 'news') {
+ User::assertPermission("news.save");
+ if (!$this->saveNews()) {
+ // re-set the fields we got
+ $this->newsTitle = Request::post('news-title', false, 'string');
+ $this->newsContent = Request::post('news-content', false, 'string');
+ } else {
+ Message::addSuccess('news-save-success');
+ $lastId = Database::lastInsertId();
+ Util::redirect("?do=News&newsid=$lastId");
+ }
+ } elseif ($pageType === 'help') {
+ User::assertPermission("help.save");
+ if ($this->saveHelp()) {
+ Message::addSuccess('help-save-success');
+ $lastId = Database::lastInsertId();
+ Util::redirect("?do=News&newsid=$lastId");
+ }
+ }
+ } elseif ($action === 'delete') {
+ // delete it
+ $pageType = Request::post('news-type');
- if ($pageType == 'news') {
- if(User::hasPermission("news.delete")) {
- $this->delNews(Request::post('newsid'));
- Util::redirect('?do=News&editHelp='.Request::any('editHelp'));
- }
- } elseif ($pageType == 'help') {
- if(User::hasPermission("help.delete")) {
- $this->delNews(Request::post('newsid'));
- Util::redirect('?do=News&editHelp='.Request::any('editHelp'));
- }
- }
- } else {
- // unknown action, redirect user
- Message::addError('invalid-action', $action);
- }
- }
+ if ($pageType === 'news') {
+ User::assertPermission("news.delete");
+ $this->delNews(Request::post('newsid'));
+ Util::redirect('?do=News&editHelp=' . Request::any('editHelp'));
+ } elseif ($pageType === 'help') {
+ User::assertPermission("help.delete");
+ $this->delNews(Request::post('newsid'));
+ Util::redirect('?do=News&editHelp=' . Request::any('editHelp'));
+ }
+ } else {
+ // unknown action, redirect user
+ Message::addError('invalid-action', $action);
+ }
+ }
- /**
- * Implementation of the abstract doRender function.
- *
- * Fetch the list of news from the database and paginate it.
- */
- protected function doRender()
- {
- // fetch the list of the older news
- $lines = array();
- $paginate = new Paginate("SELECT newsid, dateline, title, content FROM vmchooser_pages WHERE type='news' ORDER BY dateline DESC", 10);
- $res = $paginate->exec();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $row['date'] = date('d.m.Y H:i', $row['dateline']);
+ /**
+ * Implementation of the abstract doRender function.
+ *
+ * Fetch the list of news from the database and paginate it.
+ */
+ protected function doRender()
+ {
+ // fetch the list of the older news
+ $lines = array();
+ $paginate = new Paginate("SELECT newsid, dateline, title, content FROM vmchooser_pages WHERE type='news' ORDER BY dateline DESC", 10);
+ $res = $paginate->exec();
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $row['date'] = date('d.m.Y H:i', $row['dateline']);
- if ($row['newsid'] == $this->newsId) {
- $row['active'] = 'active';
- }
- $row['content'] = strip_tags(str_replace('>', '> ', $row['content']));
- $lines[] = $row;
- }
- // fetch the list of the older helps
- $linesHelp = array();
- $paginateHelp = new Paginate("SELECT newsid, dateline, content FROM vmchooser_pages WHERE type='help' ORDER BY dateline DESC", 10);
- $resHelp = $paginateHelp->exec();
- while ($row = $resHelp->fetch(PDO::FETCH_ASSOC)) {
- $row['date'] = date('d.m.Y H:i', $row['dateline']);
- if ($row['newsid'] == $this->newsId) {
- $row['active'] = 'active';
- }
- $row['content'] = strip_tags(str_replace('>', '> ', $row['content']));
- $linesHelp[] = $row;
- }
+ if ($row['newsid'] == $this->newsId) {
+ $row['active'] = 'active';
+ }
+ $row['content'] = strip_tags(str_replace('>', '> ', $row['content']));
+ $lines[] = $row;
+ }
+ // fetch the list of the older helps
+ $linesHelp = array();
+ $paginateHelp = new Paginate("SELECT newsid, dateline, content FROM vmchooser_pages WHERE type='help' ORDER BY dateline DESC", 10);
+ $resHelp = $paginateHelp->exec();
+ while ($row = $resHelp->fetch(PDO::FETCH_ASSOC)) {
+ $row['date'] = date('d.m.Y H:i', $row['dateline']);
+ if ($row['newsid'] == $this->newsId) {
+ $row['active'] = 'active';
+ }
+ $row['content'] = strip_tags(str_replace('>', '> ', $row['content']));
+ $linesHelp[] = $row;
+ }
- $paginate->render('page-news', array(
- 'token' => Session::get('token'),
- 'latestDate' => ($this->newsDate ? date('d.m.Y H:i', $this->newsDate) : '--'),
- 'latestContent' => $this->newsContent,
- 'latestTitle' => $this->newsTitle,
- 'latestHelp' => $this->helpContent,
- 'editHelp' => $this->editHelp,
- 'list' => $lines,
- 'listHelp' => $linesHelp,
- 'allowedNewsSave' => User::hasPermission("news.save"),
- 'allowedNewsDelete' => User::hasPermission("news.delete"),
- 'allowedHelpSave' => User::hasPermission("help.save"),
- 'allowedHelpDelete' => User::hasPermission("help.delete"),
- 'hasSummernote' => $this->hasSummernote, ));
- }
- /**
- * Loads the news with the given ID into the form.
- *
- * @param int $newsId ID of the news to be shown.
- *
- * @return bool true if loading that news worked
- */
- private function loadNews($newsId)
- {
- // check to see if we need to request a specific newsid
- if ($newsId !== false) {
- $row = Database::queryFirst('SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE newsid = :newsid LIMIT 1', array(
- 'newsid' => $newsId,
- ));
- } else {
- $row = Database::queryFirst("SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE type='news' ORDER BY dateline DESC LIMIT 1");
- }
+ $data = array(
+ 'token' => Session::get('token'),
+ 'latestDate' => ($this->newsDate ? date('d.m.Y H:i', $this->newsDate) : '--'),
+ 'latestContent' => $this->newsContent,
+ 'latestTitle' => $this->newsTitle,
+ 'latestHelp' => $this->helpContent,
+ 'editHelp' => $this->editHelp,
+ 'list' => $lines,
+ 'listHelp' => $linesHelp,
+ 'hasSummernote' => $this->hasSummernote,
+ );
+ Permission::addGlobalTags($data['perms'], null, ['news.save', 'news.delete', 'help.save', 'help.delete']);
- // fetch the news to be shown
- if ($row !== false) {
- if ($row['type'] == 'news') {
- $this->newsId = $row['newsid'];
- $this->newsTitle = $row['title'];
- $this->newsContent = $row['content'];
- $this->newsDate = $row['dateline'];
- $this->editHelp = false;
- } else {
- $this->editHelp = true;
- $this->helpContent = $row['content'];
- }
- }
+ $paginate->render('page-news', $data);
+ }
- return $row !== false;
- }
+ /**
+ * Loads the news with the given ID into the form.
+ *
+ * @param int $newsId ID of the news to be shown.
+ *
+ * @return bool true if loading that news worked
+ */
+ private function loadNews($newsId)
+ {
+ // check to see if we need to request a specific newsid
+ if ($newsId !== false) {
+ $row = Database::queryFirst('SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE newsid = :newsid LIMIT 1', array(
+ 'newsid' => $newsId,
+ ));
+ } else {
+ $row = Database::queryFirst("SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE type='news' ORDER BY dateline DESC LIMIT 1");
+ }
- private function loadLatest($type)
- {
- $row = Database::queryFirst("SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE type=:type ORDER BY dateline DESC LIMIT 1", ['type' => $type]);
- if ($row !== false) {
- if ($row['type'] == 'news') {
- $this->newsId = $row['newsid'];
- $this->newsTitle = $row['title'];
- $this->newsContent = $row['content'];
- $this->newsDate = $row['dateline'];
- } else {
- $this->helpContent = $row['content'];
- }
- }
- }
+ // fetch the news to be shown
+ if ($row !== false) {
+ if ($row['type'] == 'news') {
+ $this->newsId = $row['newsid'];
+ $this->newsTitle = $row['title'];
+ $this->newsContent = $row['content'];
+ $this->newsDate = $row['dateline'];
+ $this->editHelp = false;
+ } else {
+ $this->editHelp = true;
+ $this->helpContent = $row['content'];
+ }
+ }
- /**
- * Save the given $newsTitle and $newsContent as POST'ed into the database.
- */
- private function saveNews()
- {
- // check if news content were set by the user
- $newsTitle = Request::post('news-title');
- $newsContent = Request::post('news-content');
- if ($newsContent !== '' && $newsTitle !== '') {
- // we got title and content, save it to DB
- Database::exec("INSERT INTO vmchooser_pages (dateline, title, content, type) VALUES (:dateline, :title, :content, 'news')", array(
- 'dateline' => time(),
- 'title' => $newsTitle,
- 'content' => $newsContent,
- ));
+ return $row !== false;
+ }
- return true;
- } else {
- Message::addError('main.empty-field');
+ private function loadLatest($type)
+ {
+ $row = Database::queryFirst("SELECT newsid, title, content, dateline, type FROM vmchooser_pages WHERE type=:type ORDER BY dateline DESC LIMIT 1", ['type' => $type]);
+ if ($row !== false) {
+ if ($row['type'] == 'news') {
+ $this->newsId = $row['newsid'];
+ $this->newsTitle = $row['title'];
+ $this->newsContent = $row['content'];
+ $this->newsDate = $row['dateline'];
+ } else {
+ $this->helpContent = $row['content'];
+ }
+ }
+ }
- return false;
- }
- }
- private function saveHelp()
- {
- $content = Request::post('help-content');
- if ($content !== '') {
- Database::exec("INSERT INTO vmchooser_pages (dateline, content, type) VALUES (:dateline, :content, 'help')", array(
- 'dateline' => time(),
- 'content' => $content,
- ));
+ /**
+ * Save the given $newsTitle and $newsContent as POST'ed into the database.
+ */
+ private function saveNews()
+ {
+ // check if news content were set by the user
+ $newsTitle = Request::post('news-title');
+ $newsContent = Request::post('news-content');
+ if ($newsContent !== '' && $newsTitle !== '') {
+ // we got title and content, save it to DB
+ Database::exec("INSERT INTO vmchooser_pages (dateline, title, content, type) VALUES (:dateline, :title, :content, 'news')", array(
+ 'dateline' => time(),
+ 'title' => $newsTitle,
+ 'content' => $newsContent,
+ ));
+
+ return true;
+ } else {
+ Message::addError('main.empty-field');
+
+ return false;
+ }
+ }
- return true;
- } else {
- Message::addError('main.empty-field');
+ private function saveHelp()
+ {
+ $content = Request::post('help-content');
+ if ($content !== '') {
+ Database::exec("INSERT INTO vmchooser_pages (dateline, content, type) VALUES (:dateline, :content, 'help')", array(
+ 'dateline' => time(),
+ 'content' => $content,
+ ));
- return false;
- }
- }
+ return true;
+ } else {
+ Message::addError('main.empty-field');
- /**
- * Delete the news entry with ID $newsId.
- *
- * @param int $newsId ID of the entry to be deleted.
- */
- private function delNews($newsId)
- {
- // sanity check: is newsId even numeric?
- if (!is_numeric($newsId)) {
- Message::addError('main.value-invalid', 'newsid', $newsId);
- } else {
- // check passed - do delete
- Database::exec('DELETE FROM vmchooser_pages WHERE newsid = :newsid LIMIT 1', array(
- 'newsid' => $newsId,
- ));
- Message::addSuccess('news-del-success');
- }
- }
+ return false;
+ }
+ }
+
+ /**
+ * Delete the news entry with ID $newsId.
+ *
+ * @param int $newsId ID of the entry to be deleted.
+ */
+ private function delNews($newsId)
+ {
+ // sanity check: is newsId even numeric?
+ if (!is_numeric($newsId)) {
+ Message::addError('main.value-invalid', 'newsid', $newsId);
+ } else {
+ // check passed - do delete
+ Database::exec('DELETE FROM vmchooser_pages WHERE newsid = :newsid LIMIT 1', array(
+ 'newsid' => $newsId,
+ ));
+ Message::addSuccess('news-del-success');
+ }
+ }
}
diff --git a/modules-available/news/permissions/permissions.json b/modules-available/news/permissions/permissions.json
index 321e73ea..953599df 100644
--- a/modules-available/news/permissions/permissions.json
+++ b/modules-available/news/permissions/permissions.json
@@ -1,6 +1,17 @@
-[
- "news.save",
- "news.delete",
- "help.save",
- "help.delete"
-] \ No newline at end of file
+{
+ "access-page": {
+ "location-aware": false
+ },
+ "help.delete": {
+ "location-aware": false
+ },
+ "help.save": {
+ "location-aware": false
+ },
+ "news.delete": {
+ "location-aware": false
+ },
+ "news.save": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/news/templates/page-news.html b/modules-available/news/templates/page-news.html
index 6293b62d..b22b44f5 100644
--- a/modules-available/news/templates/page-news.html
+++ b/modules-available/news/templates/page-news.html
@@ -11,18 +11,18 @@
<p>{{lang_newsIntro}}</p>
<div class="form-group">
<label for="news-title-id">{{lang_title}}</label>
- <input type="text" name="news-title" id ="news-title-id" class="form-control" placeholder="{{welcome}}" value="{{latestTitle}}">
+ <input type="text" name="news-title" id ="news-title-id" class="form-control" placeholder="{{welcome}}" value="{{latestTitle}}" {{perms.news.save.readonly}}>
</div>
<div class="form-group">
<label for="news-content-id">{{lang_content}}</label>
- <textarea name="news-content" id ="news-content-id" class="form-control summernote" rows="5" cols="30" placeholder="">{{latestContent}}</textarea>
+ <textarea name="news-content" id ="news-content-id" class="form-control summernote" rows="5" cols="30" {{perms.news.save.readonly}}>{{latestContent}}</textarea>
</div>
<div class="row">
<div class="text-left col-md-6">
<p>{{lang_latestUpdate}}: {{latestDate}}</p>
</div>
<div class="text-right col-md-6">
- <button {{^allowedNewsSave}}disabled{{/allowedNewsSave}} class="btn btn-primary sn-btn" name="news-type" value="news" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button {{perms.news.save.disabled}} class="btn btn-primary sn-btn" name="news-type" value="news" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
<input type="hidden" name="token" value="{{token}}">
</div>
</div>
@@ -57,7 +57,7 @@
</td>
<td class="text-center">
<input type="hidden" name="news-type" value="news">
- <button {{^allowedNewsDelete}}disabled{{/allowedNewsDelete}} class="btn btn-danger btn-xs" type="submit" name="newsid" value="{{newsid}}"><span class="glyphicon glyphicon-trash"></span></button>
+ <button {{perms.news.delete.disabled}} class="btn btn-danger btn-xs btn-delete" type="submit" name="newsid" value="{{newsid}}"><span class="glyphicon glyphicon-trash"></span></button>
</td>
</tr>
{{/list}}
@@ -74,10 +74,10 @@
<div class="form-group">
<br/>
<label for="news-content-id">{{lang_content}}</label>
- <textarea name="help-content" id="help-content-id" class="form-control summernote" style="min-height:400px" placeholder="">{{latestHelp}}</textarea>
+ <textarea name="help-content" id="help-content-id" class="form-control summernote" style="min-height:400px" {{perms.help.save.readonly}}>{{latestHelp}}</textarea>
</div>
<div class="text-right">
- <button {{^allowedHelpSave}}disabled{{/allowedHelpSave}} class="btn btn-primary sn-btn" name="news-type" value="help" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button {{perms.help.save.disabled}} class="btn btn-primary sn-btn" name="news-type" value="help" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
<input type="hidden" name="token" value="{{token}}">
</div>
</form>
@@ -108,7 +108,7 @@
</td>
<td class="text-center">
<input type="hidden" name="news-type" value="help">
- <button {{^allowedHelpDelete}}disabled{{/allowedHelpDelete}} class="btn btn-danger btn-xs" type="submit" name="newsid" value="{{newsid}}"><span class="glyphicon glyphicon-trash"></span></button>
+ <button {{perms.help.delete.disabled}} class="btn btn-danger btn-xs btn-delete" type="submit" name="newsid" value="{{newsid}}"><span class="glyphicon glyphicon-trash"></span></button>
</td>
</tr>
{{/listHelp}}
@@ -129,5 +129,11 @@ document.addEventListener("DOMContentLoaded", function () {
$button.click();
}
});
+ $('.summernote[readonly]').each(function() { $(this).summernote('disable'); });
+ $('.btn-delete').click(function (event) {
+ if (confirm('{{lang_confirmDelete}}'))
+ return;
+ event.preventDefault();
+ });
}, false);
// --></script> \ No newline at end of file
diff --git a/modules-available/permissionmanager/api.inc.php b/modules-available/permissionmanager/api.inc.php
deleted file mode 100644
index 0d84ebce..00000000
--- a/modules-available/permissionmanager/api.inc.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-echo json_encode(array(
- 'key' => 'value',
- 'number' => 123,
- 'list' => array(1,2,3,4,5,6,'foo')
-));
diff --git a/modules-available/permissionmanager/clientscript.js b/modules-available/permissionmanager/clientscript.js
index 4770fa6a..90d66688 100644
--- a/modules-available/permissionmanager/clientscript.js
+++ b/modules-available/permissionmanager/clientscript.js
@@ -10,36 +10,21 @@ document.addEventListener("DOMContentLoaded", function() {
plugins: ["remove_button"]
})[0].selectize;
- // If Site gets refreshed, all data-selectizeCounts will be reset to 0, so delete the filters from the selectize
- selectize.clear();
-
- selectize.on("item_add", function (value, $item) {
- // When first item gets added the filter isn't empty anymore, so hide all rows
- if (selectize.items.length === 1) {
- $(".dataTable tbody").find("tr").hide();
- }
- // Find all rows which shall be shown and increase their counter by 1
- $(".roleid-" + value).closest("tr").each(function () {
- $(this).data("selectizeCount", $(this).data("selectizeCount") + 1);
- $(this).show();
- });
- });
-
- selectize.on("item_remove", function (value, $item) {
- // When no items in the filter, show all rows again
- if (selectize.items.length === 0) {
- $(".dataTable tbody").find("tr").show();
+ var $body = $(".dataTable tbody");
+ var filterFunc = function(value) {
+ var selected = selectize.getValue();
+ if (!selected || !selected.length) {
+ $body.find("tr").show();
} else {
- // Find all rows which have the delete role, decrease their counter by 1
- $(".roleid-" + value).closest("tr").each(function () {
- $(this).data("selectizeCount", $(this).data("selectizeCount") - 1);
- // If counter is 0, hide the row (no filter given to show the row anymore)
- if ($(this).data("selectizeCount") === 0) {
- $(this).closest("tr").hide();
- }
- });
+ $body.find("tr").hide();
+ var str = 'tr.roleid-' + selected.join('.roleid-');
+ $body.find(str).show();
}
- });
+ };
+
+ selectize.on("item_add", filterFunc);
+
+ selectize.on("item_remove",filterFunc);
}
$("tr").on("click", function(e) {
@@ -47,8 +32,4 @@ document.addEventListener("DOMContentLoaded", function() {
$(this).find("input[type=checkbox]").trigger("click");
}
});
-
- $("form input").keydown(function(e) {
- if (e.keyCode === 13) e.preventDefault();
- });
}); \ No newline at end of file
diff --git a/modules-available/permissionmanager/config.json b/modules-available/permissionmanager/config.json
index c92e917a..25b61de3 100644
--- a/modules-available/permissionmanager/config.json
+++ b/modules-available/permissionmanager/config.json
@@ -1,4 +1,8 @@
{
- "category":"main.content",
- "dependencies": [ "locations", "js_stupidtable", "bootstrap_switch", "js_selectize" ]
-}
+ "category": "main.content",
+ "dependencies": [
+ "locations",
+ "js_stupidtable",
+ "js_selectize"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/permissionmanager/hooks/translation-global.inc.php b/modules-available/permissionmanager/hooks/translation-global.inc.php
new file mode 100644
index 00000000..4810a719
--- /dev/null
+++ b/modules-available/permissionmanager/hooks/translation-global.inc.php
@@ -0,0 +1,38 @@
+<?php
+
+$HANDLER = array();
+
+if (file_exists('modules/' . $moduleName . '/permissions/permissions.json')) {
+
+ /**
+ * List of valid subsections
+ */
+ $HANDLER['subsections'] = array(
+ 'permissions'
+ );
+
+ /*
+ * Handlers for the subsections that will return an array of expected tags.
+ * This is optional, if you don't want to define expected tags, don't create a function.
+ */
+
+ /**
+ * Configuration categories.
+ *
+ * @param \Module $module
+ * @return array
+ */
+ $HANDLER['grep_permissions'] = function ($module) {
+ $file = 'modules/' . $module->getIdentifier() . '/permissions/permissions.json';
+ if (!file_exists($file))
+ return [];
+ $array = json_decode(file_get_contents($file), true);
+ if (!is_array($array))
+ return [];
+ foreach ($array as &$entry) {
+ $entry = true;
+ }
+ return $array;
+ };
+
+}
diff --git a/modules-available/permissionmanager/inc/getpermissiondata.inc.php b/modules-available/permissionmanager/inc/getpermissiondata.inc.php
index 982fa0b7..660c94ae 100644
--- a/modules-available/permissionmanager/inc/getpermissiondata.inc.php
+++ b/modules-available/permissionmanager/inc/getpermissiondata.inc.php
@@ -1,27 +1,32 @@
<?php
-class GetPermissionData {
+class GetPermissionData
+{
+
+ const WITH_USER_COUNT = 1;
+ const WITH_LOCATION_COUNT = 2;
/**
* Get data for all users.
*
* @return array array of users (each with userid, username and roles (each with roleid and rolename))
*/
- public static function getUserData() {
+ public static function getUserData()
+ {
$res = Database::simpleQuery("SELECT user.userid AS userid, user.login AS login, role.rolename AS rolename, role.roleid AS roleid
FROM user
- LEFT JOIN user_x_role ON user.userid = user_x_role.userid
- LEFT JOIN role ON user_x_role.roleid = role.roleid
+ LEFT JOIN role_x_user ON user.userid = role_x_user.userid
+ LEFT JOIN role ON role_x_user.roleid = role.roleid
");
- $userdata= array();
+ $userdata = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $userdata[$row['userid'].' '.$row['login']][] = array(
+ $userdata[$row['userid'] . ' ' . $row['login']][] = array(
'roleid' => $row['roleid'],
'rolename' => $row['rolename']
);
}
$data = array();
- foreach($userdata AS $user => $roles) {
+ foreach ($userdata AS $user => $roles) {
$user = explode(" ", $user, 2);
$data[] = array(
'userid' => $user[0],
@@ -37,8 +42,9 @@ class GetPermissionData {
*
* @return array array of locations (each including the roles that have permissions for them)
*/
- public static function getLocationData() {
- $res = Database::simpleQuery("SELECT role.roleid as roleid, rolename, GROUP_CONCAT(COALESCE(locationid, 0)) AS locationids FROM role
+ public static function getLocationData()
+ {
+ $res = Database::simpleQuery("SELECT role.roleid AS roleid, rolename, GROUP_CONCAT(COALESCE(locationid, 0)) AS locationids FROM role
INNER JOIN role_x_location ON role.roleid = role_x_location.roleid GROUP BY roleid ORDER BY rolename ASC");
$locations = Location::getLocations(0, 0, false, true);
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
@@ -61,18 +67,26 @@ class GetPermissionData {
/**
* Get all roles.
*
+ * @param int $flags Bitmask specifying additional data to fetch (WITH_* constants of this class)
* @return array array roles (each with roleid and rolename)
*/
- public static function getRoles() {
- $res = Database::simpleQuery("SELECT roleid, rolename FROM role ORDER BY rolename ASC");
- $data = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $data[] = array(
- 'roleid' => $row['roleid'],
- 'rolename' => $row['rolename']
- );
+ public static function getRoles($flags = 0)
+ {
+ $cols = $joins = '';
+ if ($flags & self::WITH_USER_COUNT) {
+ $cols .= ', Count(DISTINCT rxu.userid) AS users';
+ $joins .= ' LEFT JOIN role_x_user rxu ON (r.roleid = rxu.roleid)';
}
- return $data;
+ if ($flags & self::WITH_LOCATION_COUNT) {
+ $cols .= ', Count(DISTINCT rxl.locationid) AS locations';
+ $joins .= ' LEFT JOIN role_x_location rxl ON (r.roleid = rxl.roleid)';
+ }
+ if (!empty($joins)) {
+ $joins .= ' GROUP BY r.roleid';
+ }
+ return Database::queryAll("SELECT r.roleid, r.rolename, r.roledescription $cols FROM role r
+ $joins
+ ORDER BY rolename ASC");
}
/**
@@ -81,8 +95,9 @@ class GetPermissionData {
* @param string $roleid id of the role
* @return array array containing an array of permissions and an array of locations
*/
- public static function getRoleData($roleid) {
- $query = "SELECT roleid, rolename FROM role WHERE roleid = :roleid";
+ public static function getRoleData($roleid)
+ {
+ $query = "SELECT roleid, rolename, roledescription FROM role WHERE roleid = :roleid";
$data = Database::queryFirst($query, array("roleid" => $roleid));
$query = "SELECT roleid, locationid FROM role_x_location WHERE roleid = :roleid";
$res = Database::simpleQuery($query, array("roleid" => $roleid));
diff --git a/modules-available/permissionmanager/inc/permissiondbupdate.inc.php b/modules-available/permissionmanager/inc/permissiondbupdate.inc.php
index ffe5fac0..0cd89b3a 100644
--- a/modules-available/permissionmanager/inc/permissiondbupdate.inc.php
+++ b/modules-available/permissionmanager/inc/permissiondbupdate.inc.php
@@ -1,67 +1,107 @@
<?php
-class PermissionDbUpdate {
+class PermissionDbUpdate
+{
/**
- * Insert all user/role combinations into the user_x_role table.
+ * Insert all user/role combinations into the role_x_user table.
*
- * @param array $users userids
- * @param array $roles roleids
+ * @param int[] $users userids
+ * @param int[] $roles roleids
*/
- public static function addRoleToUser($users, $roles) {
- $query = "INSERT IGNORE INTO user_x_role (userid, roleid) VALUES (:userid, :roleid)";
- foreach($users AS $userid) {
+ public static function addRoleToUser($users, $roles)
+ {
+ if (empty($users) || empty($roles))
+ return 0;
+ $arg = array();
+ foreach ($users AS $userid) {
foreach ($roles AS $roleid) {
- Database::exec($query, array("userid" => $userid, "roleid" => $roleid));
+ $arg[] = compact('userid', 'roleid');
}
}
+ return Database::exec("INSERT IGNORE INTO role_x_user (userid, roleid) VALUES :arg",
+ ['arg' => $arg]);
}
/**
- * Remove all user/role combinations from the user_x_role table.
+ * Remove all user/role combinations from the role_x_user table.
*
- * @param array $users userids
- * @param array $roles roleids
+ * @param int[] $users userids
+ * @param int[] $roles roleids
*/
- public static function removeRoleFromUser($users, $roles) {
- $query = "DELETE FROM user_x_role WHERE userid IN (:users) AND roleid IN (:roles)";
- Database::exec($query, array("users" => $users, "roles" => $roles));
+ public static function removeRoleFromUser($users, $roles)
+ {
+ if (empty($users) || empty($roles))
+ return 0;
+ $query = "DELETE FROM role_x_user WHERE userid IN (:users) AND roleid IN (:roles)";
+ return Database::exec($query, array("users" => $users, "roles" => $roles));
+ }
+
+ /**
+ * Assign the specified roles to given users, removing any roles from the users
+ * that are not in the given set.
+ *
+ * @param int[] $users list of user ids
+ * @param int[] $roles list of role ids
+ */
+ public static function setRolesForUser($users, $roles)
+ {
+ $count = Database::exec("DELETE FROM role_x_user WHERE userid in (:users) AND roleid NOT IN (:roles)",
+ compact('users', 'roles'));
+ return $count + self::addRoleToUser($users, $roles);
}
/**
* Delete role from the role table.
*
- * @param string $roleid roleid
+ * @param int $roleid roleid
*/
- public static function deleteRole($roleid) {
- Database::exec("DELETE FROM role WHERE roleid = :roleid", array("roleid" => $roleid));
+ public static function deleteRole($roleid)
+ {
+ return Database::exec("DELETE FROM role WHERE roleid = :roleid", array("roleid" => $roleid));
}
/**
* Save changes to a role or create a new one.
*
- * @param string $rolename rolename
- * @param array $locations array of locations
- * @param array $permissions array of permissions
- * @param string|null $roleid roleid or null if the role does not exist yet
+ * @param string $roleName rolename
+ * @param int[] $locations array of locations
+ * @param string[] $permissions array of permissions
+ * @param int|null $roleId roleid or null if the role does not exist yet
*/
- public static function saveRole($rolename, $locations, $permissions, $roleid = NULL) {
- if ($roleid) {
- Database::exec("UPDATE role SET rolename = :rolename WHERE roleid = :roleid",
- array("rolename" => $rolename, "roleid" => $roleid));
- Database::exec("DELETE FROM role_x_location WHERE roleid = :roleid", array("roleid" => $roleid));
- Database::exec("DELETE FROM role_x_permission WHERE roleid = :roleid", array("roleid" => $roleid));
+ public static function saveRole($roleName, $roleDescription, $locations, $permissions, $roleId = null)
+ {
+ foreach ($permissions as &$permission) {
+ $permission = strtolower($permission);
+ }
+ unset($permission);
+ if ($roleId) {
+ Database::exec("UPDATE role SET rolename = :rolename, roledescription = :roledescription WHERE roleid = :roleid",
+ array("rolename" => $roleName, "roledescription" => $roleDescription, "roleid" => $roleId));
+ Database::exec("DELETE FROM role_x_location
+ WHERE roleid = :roleid AND (locationid NOT IN (:locations) OR locationid IS NULL)",
+ array("roleid" => $roleId, 'locations' => $locations));
+ Database::exec("DELETE FROM role_x_permission
+ WHERE roleid = :roleid AND permissionid NOT IN (:permissions)",
+ array("roleid" => $roleId, 'permissions' => $permissions));
} else {
- Database::exec("INSERT INTO role (rolename) VALUES (:rolename)", array("rolename" => $rolename));
- $roleid = Database::lastInsertId();
+ Database::exec("INSERT INTO role (rolename, roledescription) VALUES (:rolename, :roledescription)",
+ array("rolename" => $roleName, "roledescription" => $roleDescription));
+ $roleId = Database::lastInsertId();
}
- foreach ($locations as $locationid) {
- Database::exec("INSERT INTO role_x_location (roleid, locationid) VALUES (:roleid, :locationid)",
- array("roleid" => $roleid, "locationid" => $locationid));
+
+ if (!empty($locations)) {
+ $arg = array_map(function ($loc) use ($roleId) {
+ return compact('roleId', 'loc');
+ }, $locations);
+ Database::exec("INSERT IGNORE INTO role_x_location (roleid, locationid) VALUES :arg", ['arg' => $arg]);
}
- foreach ($permissions as $permissionid) {
- Database::exec("INSERT INTO role_x_permission (roleid, permissionid) VALUES (:roleid, :permissionid)",
- array("roleid" => $roleid, "permissionid" => $permissionid));
+
+ if (!empty($permissions)) {
+ $arg = array_map(function ($perm) use ($roleId) {
+ return compact('roleId', 'perm');
+ }, $permissions);
+ Database::exec("INSERT IGNORE INTO role_x_permission (roleid, permissionid) VALUES :arg", ['arg' => $arg]);
}
}
diff --git a/modules-available/permissionmanager/inc/permissionutil.inc.php b/modules-available/permissionmanager/inc/permissionutil.inc.php
index 5ff41046..a3a2b610 100644
--- a/modules-available/permissionmanager/inc/permissionutil.inc.php
+++ b/modules-available/permissionmanager/inc/permissionutil.inc.php
@@ -2,6 +2,44 @@
class PermissionUtil
{
+
+ /**
+ * Generate all possible variants to match against, eg. $permissionid = a.b.c then we get:
+ * [ *, a.*, a.b.*, a.b.c ]
+ * In case $permissionid ends with an asterisk, also set $wildcard and $wclen, e.g.
+ * $permissionid = a.b.* --> $wildcard = a.b. and $wclen = 4
+ *
+ * @param $permission string|string[] permission to mangle
+ * @param string[] $compare all the generated variants
+ * @param string|false $wildcard if $permission is a wildcard string this returns the matching variant
+ * @param int|false $wclen if $permission is a wildcard string, this is the length of the matching variant
+ */
+ private static function makeComparisonVariants($permission, &$compare, &$wildcard, &$wclen)
+ {
+ if (!is_array($permission)) {
+ $permission = explode('.', $permission);
+ }
+ $partCount = count($permission);
+ $compare = [];
+ for ($i = 0; $i < $partCount; ++$i) {
+ $compare[] = $permission[0];
+ }
+ for ($i = 1; $i < $partCount; ++$i) {
+ $compare[$i - 1] .= '.*';
+ for ($j = $i; $j < $partCount; ++$j) {
+ $compare[$j] .= '.' . $permission[$i];
+ }
+ }
+ $compare[] = '*';
+
+ if ($permission[$partCount - 1] === '*') {
+ $wildcard = substr($compare[$partCount - 1], 0, -1);
+ $wclen = strlen($wildcard);
+ } else {
+ $wclen = $wildcard = false;
+ }
+ }
+
/**
* Check if the user has the given permission (for the given location).
*
@@ -10,26 +48,48 @@ class PermissionUtil
* @param int|null $locationid locationid to check or null if the location should be disregarded
* @return bool true if user has permission, false if not
*/
- public static function userHasPermission($userid, $permissionid, $locationid) {
- $locations = array();
- if (!is_null($locationid)) {
- $locations = Location::getLocationRootChain($locationid);
- if (count($locations) == 0) return false;
- else $locations[] = 0;
+ public static function userHasPermission($userid, $permissionid, $locationid)
+ {
+ $permissionid = strtolower($permissionid);
+ self::validatePermission($permissionid);
+ $parts = explode('.', $permissionid);
+ // Special case: To prevent lockout, userid === 1 always has permissionmanager.*
+ if ($parts[0] === 'permissionmanager' && User::getId() === 1)
+ return true;
+ // Limit query to first part of permissionid, which is always the module id
+ $prefix = $parts[0] . '.%';
+ if (is_null($locationid)) {
+ $res = Database::simpleQuery("SELECT permissionid FROM role_x_permission
+ INNER JOIN role_x_user USING (roleid)
+ WHERE role_x_user.userid = :userid AND (permissionid LIKE :prefix OR permissionid LIKE '*')",
+ compact('userid', 'prefix'));
+ } else {
+ if ($locationid === 0) {
+ $locations = [0];
+ } else {
+ $locations = Location::getLocationRootChain($locationid);
+ if (empty($locations)) { // Non-existent location, still continue as user might have global perms
+ $locations = [0];
+ }
+ }
+ $res = Database::simpleQuery("SELECT permissionid FROM role_x_permission
+ INNER JOIN role_x_user USING (roleid)
+ INNER JOIN role_x_location USING (roleid)
+ WHERE role_x_user.userid = :userid AND (permissionid LIKE :prefix OR permissionid LIKE '*')
+ AND (locationid IN (:locations) OR locationid IS NULL)",
+ compact('userid', 'prefix', 'locations'));
}
+ // Quick bailout - no results
+ if ($res->rowCount() === 0)
+ return false;
- $res = Database::simpleQuery("SELECT permissionid, locationid FROM user_x_role
- INNER JOIN role_x_permission ON user_x_role.roleid = role_x_permission.roleid
- LEFT JOIN (SELECT roleid, COALESCE(locationid, 0) AS locationid FROM role_x_location) t1
- ON role_x_permission.roleid = t1.roleid
- WHERE user_x_role.userid = :userid", array("userid" => $userid));
-
+ // Compare to database result
+ self::makeComparisonVariants($parts, $compare, $wildcard, $wclen);
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $userPermission = rtrim($row["permissionid"], ".*").".";
- if ((is_null($locationid) || (!is_null($row["locationid"]) && in_array($row["locationid"], $locations))) &&
- (substr($permissionid.".", 0, strlen($userPermission)) === $userPermission || $userPermission === ".")) {
+ if (in_array($row['permissionid'], $compare, true))
+ return true;
+ if ($wildcard !== false && strncmp($row['permissionid'], $wildcard, $wclen) === 0)
return true;
- }
}
return false;
}
@@ -41,26 +101,40 @@ class PermissionUtil
* @param string $permissionid permissionid to check
* @return array array of locationids where the user has the given permission
*/
- public static function getAllowedLocations($userid, $permissionid) {
-
- $res = Database::simpleQuery("SELECT permissionid, COALESCE(locationid, 0) AS locationid FROM user_x_role
- INNER JOIN role_x_permission ON user_x_role.roleid = role_x_permission.roleid
- INNER JOIN role_x_location ON role_x_permission.roleid = role_x_location.roleid
- WHERE user_x_role.userid = :userid", array("userid" => $userid));
+ public static function getAllowedLocations($userid, $permissionid)
+ {
+ $permissionid = strtolower($permissionid);
+ self::validatePermission($permissionid);
+ $parts = explode('.', $permissionid);
+ // Special case: To prevent lockout, userid === 1 always has permissionmanager.*
+ if ($parts[0] === 'permissionmanager' && User::getId() === 1) {
+ $allowedLocations = [true];
+ } else {
+ // Limit query to first part of permissionid, which is always the module id
+ $prefix = $parts[0] . '.%';
+ $res = Database::simpleQuery("SELECT permissionid, locationid FROM role_x_permission
+ INNER JOIN role_x_user USING (roleid)
+ INNER JOIN role_x_location USING (roleid)
+ WHERE role_x_user.userid = :userid AND (permissionid LIKE :prefix OR permissionid LIKE '*')",
+ compact('userid', 'prefix'));
- $allowedLocations = array();
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $userPermission = rtrim($row["permissionid"], ".*").".";
- if (substr($permissionid.".", 0, strlen($userPermission)) === $userPermission || $userPermission === ".") {
- $allowedLocations[$row["locationid"]] = 1;
+ // Gather locationid from relevant rows
+ self::makeComparisonVariants($parts, $compare, $wildcard, $wclen);
+ $allowedLocations = array();
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (in_array($row['permissionid'], $compare, true)
+ || ($wildcard !== false && strncmp($row['permissionid'], $wildcard, $wclen) === 0)) {
+ $allowedLocations[(int)$row['locationid']] = true;
+ }
}
}
- $allowedLocations = array_keys($allowedLocations);
$locations = Location::getTree();
- if (in_array("0", $allowedLocations)) {
- $allowedLocations = array_map("intval", Location::extractIds($locations));
- $allowedLocations[] = 0;
+ if (isset($allowedLocations[0])) {
+ // Trivial case - have permission for all locations, so populate list with all valid locationds
+ $allowedLocations = Location::extractIds($locations);
+ $allowedLocations[] = 0; // .. plus 0 to show that we have global perms
} else {
+ // We have a specific list of locationds - add any sublocations to list
$allowedLocations = self::getSublocations($locations, $allowedLocations);
}
return $allowedLocations;
@@ -70,17 +144,18 @@ class PermissionUtil
* Extend an array of locations by adding all sublocations.
*
* @param array $tree tree of all locations (structured like Location::getTree())
- * @param array $locations the array of locationids to extend
+ * @param array $allowedLocations the array of locationids to extend
* @return array extended array of locationids
*/
- public static function getSublocations($tree, $locations) {
- $result = array_flip($locations);
+ public static function getSublocations($tree, $allowedLocations)
+ {
+ $result = $allowedLocations;
foreach ($tree as $location) {
if (array_key_exists("children", $location)) {
- if (in_array($location["locationid"], $locations)) {
+ if (isset($allowedLocations[$location["locationid"]])) {
$result += array_flip(Location::extractIds($location["children"]));
} else {
- $result += array_flip(self::getSublocations($location["children"], $locations));
+ $result += array_flip(self::getSublocations($location["children"], $allowedLocations));
}
}
}
@@ -88,6 +163,37 @@ class PermissionUtil
}
/**
+ * If in debug mode, validate that the checked permission is actually defined
+ * in the according permissions.json and complain if that's not the case.
+ * This is supposed to catch misspelled permission checks.
+ *
+ * @param string $permissionId permission to check
+ */
+ private static function validatePermission($permissionId)
+ {
+ if (!CONFIG_DEBUG || $permissionId === '*')
+ return;
+ $split = explode('.', $permissionId, 2);
+ if (count($split) !== 2) {
+ trigger_error('[skip:3]Cannot check malformed permission "' . $permissionId . '"', E_USER_WARNING);
+ return;
+ }
+ if ($split[1] === '*')
+ return;
+ $data = json_decode(file_get_contents('modules/' . $split[0] . '/permissions/permissions.json'), true);
+ if (substr($split[1], -2) === '.*') {
+ $len = strlen($split[1]) - 1;
+ foreach ($data as $perm => $v) {
+ if (strncmp($split[1], $perm, $len) === 0)
+ return;
+ }
+ trigger_error('[skip:3]Permission "' . $permissionId . '" does not match anything defined for module', E_USER_WARNING);
+ } elseif (!is_array($data) || !array_key_exists($split[1], $data)) {
+ trigger_error('[skip:3]Permission "' . $permissionId . '" not defined for module', E_USER_WARNING);
+ }
+ }
+
+ /**
* Get all permissions of all active modules that have permissions in their permissions/permissions.json file.
*
* @return array permission tree as a multidimensional array
@@ -100,30 +206,62 @@ class PermissionUtil
if (!is_array($data))
continue;
preg_match('#^modules/([^/]+)/#', $file, $out);
- foreach( $data as $p ) {
- $description = Dictionary::translateFileModule($out[1], "permissions", $p);
- self::putInPermissionTree($out[1].".".$p, $description, $permissions);
+ $moduleId = $out[1];
+ if (Module::get($moduleId) === false)
+ continue;
+ foreach ($data as $perm => $permissionFlags) {
+ $description = Dictionary::translateFileModule($moduleId, "permissions", $perm);
+ self::putInPermissionTree($moduleId . "." . $perm, $permissionFlags['location-aware'], $description, $permissions);
}
}
ksort($permissions);
global $MENU_CAT_OVERRIDE;
$sortingOrder = $MENU_CAT_OVERRIDE;
- foreach ($permissions as $module => $v) $sortingOrder[Module::get($module)->getCategory()][] = $module;
+ foreach ($permissions as $module => $v) {
+ $sortingOrder[Module::get($module)->getCategory()][] = $module;
+ }
$permissions = array_replace(array_flip(call_user_func_array('array_merge', $sortingOrder)), $permissions);
- foreach ($permissions as $module => $v) if (is_int($v)) unset($permissions[$module]);
+ foreach ($permissions as $module => $v) {
+ if (is_int($v)) {
+ unset($permissions[$module]);
+ }
+ }
return $permissions;
}
/**
+ * Get all existing roles.
+ *
+ * @param int|false $userid Which user to consider, false = none
+ * @param bool $onlyMatching true = filter roles the user doesn't have
+ * @return array list of roles
+ */
+ public static function getRoles($userid = false, $onlyMatching = true)
+ {
+ if ($userid === false) {
+ return Database::queryAll('SELECT roleid, rolename FROM role ORDER BY rolename ASC');
+ }
+ $ret = Database::queryAll('SELECT r.roleid, r.rolename, u.userid AS hasRole FROM role r
+ LEFT JOIN role_x_user u ON (r.roleid = u.roleid AND u.userid = :userid)
+ GROUP BY r.roleid
+ ORDER BY rolename ASC', ['userid' => $userid]);
+ foreach ($ret as &$role) {
+ settype($role['hasRole'], 'bool');
+ }
+ return $ret;
+ }
+
+ /**
* Place a permission into the given permission tree.
*
* @param string $permission the permission to place in the tree
+ * @param bool $locationAware whether this permissions can be restricted to specific locations only
* @param string $description the description of the permission
* @param array $tree the permission tree to modify
*/
- private static function putInPermissionTree($permission, $description, &$tree)
+ private static function putInPermissionTree($permission, $locationAware, $description, &$tree)
{
$subPermissions = explode('.', $permission);
foreach ($subPermissions as $subPermission) {
@@ -134,6 +272,7 @@ class PermissionUtil
$tree =& $tree[$subPermission];
}
}
- $tree = $description;
+ $tree = array('description' => $description, 'location-aware' => $locationAware, 'isLeaf' => true);
}
+
} \ No newline at end of file
diff --git a/modules-available/permissionmanager/install.inc.php b/modules-available/permissionmanager/install.inc.php
index 71ee7a1e..7f9c80ef 100644
--- a/modules-available/permissionmanager/install.inc.php
+++ b/modules-available/permissionmanager/install.inc.php
@@ -5,20 +5,27 @@ $res = array();
$res[] = tableCreate('role', "
roleid int(10) unsigned NOT NULL AUTO_INCREMENT,
rolename varchar(200) NOT NULL,
+ roledescription TEXT,
PRIMARY KEY (roleid)
");
-$res[] = tableCreate('user_x_role', "
+if (tableExists('user_x_role')) {
+ if (tableExists('role_x_user')) {
+ Database::exec('DROP TABLE user_x_role');
+ } else {
+ $res[] = tableRename('user_x_role', 'role_x_user');
+ }
+}
+$res[] = tableCreate('role_x_user', "
userid int(10) unsigned NOT NULL,
roleid int(10) unsigned NOT NULL,
PRIMARY KEY (userid, roleid)
");
$res[] = tableCreate('role_x_location', "
- id int(10) unsigned NOT NULL AUTO_INCREMENT,
roleid int(10) unsigned NOT NULL,
locationid int(11),
- PRIMARY KEY (id)
+ CONSTRAINT role_loc UNIQUE (roleid, locationid)
");
$res[] = tableCreate('role_x_permission', "
@@ -27,24 +34,38 @@ $res[] = tableCreate('role_x_permission', "
PRIMARY KEY (roleid, permissionid)
");
+if (tableHasColumn('role_x_location', 'id')) {
+ $cnt = Database::exec('DELETE a FROM role_x_location a, role_x_location b
+ WHERE a.roleid = b.roleid AND (a.locationid = b.locationid OR (a.locationid IS NULL AND b.locationid IS NULL))
+ AND a.id > b.id');
+ $ret = Database::exec('ALTER TABLE role_x_location DROP COLUMN id,
+ ADD CONSTRAINT role_loc UNIQUE (roleid, locationid)');
+ if ($ret === false) {
+ $res[] = UPDATE_NOOP;
+ } else {
+ $res[] = UPDATE_DONE;
+ }
+
+}
+
if (!tableExists('user') || !tableExists('location')) {
finalResponse(UPDATE_RETRY, 'Cannot add constraint yet. Please retry.');
} else {
- $c = tableGetContraints('user_x_role', 'userid', 'user', 'userid');
+ $c = tableGetContraints('role_x_user', 'userid', 'user', 'userid');
if ($c === false)
finalResponse(UPDATE_FAILED, 'Cannot get constraints of user table: ' . Database::lastError());
if (empty($c)) {
- $alter = Database::exec('ALTER TABLE user_x_role ADD FOREIGN KEY (userid) REFERENCES user (userid) ON DELETE CASCADE ON UPDATE CASCADE');
+ $alter = Database::exec('ALTER TABLE role_x_user ADD FOREIGN KEY (userid) REFERENCES user (userid) ON DELETE CASCADE ON UPDATE CASCADE');
if ($alter === false)
finalResponse(UPDATE_FAILED, 'Cannot add userid constraint referencing user table: ' . Database::lastError());
$res[] = UPDATE_DONE;
}
- $c = tableGetContraints('user_x_role', 'roleid', 'role', 'roleid');
+ $c = tableGetContraints('role_x_user', 'roleid', 'role', 'roleid');
if ($c === false)
finalResponse(UPDATE_FAILED, 'Cannot get constraints of role table: ' . Database::lastError());
if (empty($c)) {
- $alter = Database::exec('ALTER TABLE user_x_role ADD FOREIGN KEY (roleid) REFERENCES role (roleid) ON DELETE CASCADE ON UPDATE CASCADE');
+ $alter = Database::exec('ALTER TABLE role_x_user ADD FOREIGN KEY (roleid) REFERENCES role (roleid) ON DELETE CASCADE ON UPDATE CASCADE');
if ($alter === false)
finalResponse(UPDATE_FAILED, 'Cannot add roleid constraint referencing role table: ' . Database::lastError());
$res[] = UPDATE_DONE;
@@ -80,6 +101,108 @@ if (!tableExists('user') || !tableExists('location')) {
$res[] = UPDATE_DONE;
}
}
+
+// 2018-04-13 role description field; add a couple default roles
+if (!tableHasColumn('role', 'roledescription')) {
+ $alter = Database::exec("ALTER TABLE role ADD roledescription TEXT");
+ if ($alter === false)
+ finalResponse(UPDATE_FAILED, 'Cannot add roledescription field to table role: ' . Database::lastError());
+ $res[] = UPDATE_DONE;
+}
+
+if (!tableHasColumn('role', 'roledescription')) {
+ finalResponse(UPDATE_RETRY, 'Try again later');
+}
+
+if (Database::exec("INSERT INTO `role` VALUES
+ (1,'Super-Admin', 'Hat keinerlei Zugriffsbeschränkungen'),
+ (2,'Admin', 'Alles bis auf Rechte-/Nutzerverwaltung'),
+ (3,'Prüfungsadmin', 'Kann E-Prüfungen verwalten, Prüfungsmodus einschalten, etc.'),
+ (4,'Lesezugriff', 'Kann auf die meisten Seiten zugreifen, jedoch keine Änderungen vornehmen')") !== false) {
+ // Success, there probably were no roles before, keep going
+ // Assign roles to location (all)
+ Database::exec("INSERT INTO `role_x_location` VALUES (1,NULL),(2,NULL),(3,NULL),(4,NULL)");
+ // Assign permissions to roles
+ Database::exec("INSERT INTO `role_x_permission` VALUES
+ (3,'exams.exams.*'),
+ (3,'rebootcontrol.action.*'),
+ (3,'statistics.hardware.projectors.view'),
+ (3,'statistics.machine.note.*'),
+ (3,'statistics.machine.view-details'),
+ (3,'statistics.view.*'),
+ (3,'syslog.view'),
+
+ (1,'*'),
+
+ (4,'adduser.user.view-list'),
+ (4,'backup.create'),
+ (4,'baseconfig.view'),
+ (4,'dnbd3.access-page'),
+ (4,'dnbd3.refresh'),
+ (4,'dnbd3.view.details'),
+ (4,'dozmod.actionlog.view'),
+ (4,'dozmod.users.view'),
+ (4,'eventlog.view'),
+ (4,'exams.exams.view'),
+ (4,'locationinfo.backend.check'),
+ (4,'locationinfo.panel.list'),
+ (4,'locations.location.view'),
+ (4,'minilinux.view'),
+ (4,'news.*'),
+ (4,'permissionmanager.locations.view'),
+ (4,'permissionmanager.roles.view'),
+ (4,'permissionmanager.users.view'),
+ (4,'runmode.list-all'),
+ (4,'serversetup.access-page'),
+ (4,'serversetup.download'),
+ (4,'statistics.hardware.projectors.view'),
+ (4,'statistics.machine.note.view'),
+ (4,'statistics.machine.view-details'),
+ (4,'statistics.view.*'),
+ (4,'statistics_reporting.reporting.download'),
+ (4,'statistics_reporting.table.export'),
+ (4,'statistics_reporting.table.view.*'),
+ (4,'sysconfig.config.view-list'),
+ (4,'sysconfig.module.download'),
+ (4,'sysconfig.module.view-list'),
+ (4,'syslog.view'),
+ (4,'systemstatus.show.overview.*'),
+ (4,'systemstatus.tab.*'),
+ (4,'webinterface.access-page'),
+
+ (2,'adduser.user.view-list'),
+ (2,'backup.*'),
+ (2,'baseconfig.*'),
+ (2,'dnbd3.*'),
+ (2,'dozmod.*'),
+ (2,'eventlog.view'),
+ (2,'exams.exams.*'),
+ (2,'locationinfo.*'),
+ (2,'locations.*'),
+ (2,'minilinux.*'),
+ (2,'news.*'),
+ (2,'permissionmanager.locations.view'),
+ (2,'permissionmanager.roles.view'),
+ (2,'permissionmanager.users.view'),
+ (2,'rebootcontrol.*'),
+ (2,'roomplanner.edit'),
+ (2,'runmode.list-all'),
+ (2,'serversetup.*'),
+ (2,'statistics.*'),
+ (2,'statistics_reporting.*'),
+ (2,'sysconfig.*'),
+ (2,'syslog.*'),
+ (2,'systemstatus.*'),
+ (2,'vmstore.edit'),
+ (2,'webinterface.*')");
+ // Asign the first user to the superadmin role (if one exists)
+ Database::exec("INSERT INTO `role_x_user` VALUES (1,1)");
+ $res[] = UPDATE_DONE;
+}
+
+//
+//
+
if (in_array(UPDATE_DONE, $res)) {
finalResponse(UPDATE_DONE, 'Tables created successfully');
}
diff --git a/modules-available/permissionmanager/lang/de/permissions.json b/modules-available/permissionmanager/lang/de/permissions.json
new file mode 100644
index 00000000..444c1e8c
--- /dev/null
+++ b/modules-available/permissionmanager/lang/de/permissions.json
@@ -0,0 +1,7 @@
+{
+ "locations.view": "Orte mit zugewiesenen Rollen sehen.",
+ "roles.edit": "Rollen bearbeiten.",
+ "roles.view": "Rollen sehen.",
+ "users.edit-roles": "Benutzern Rollen zuweisen oder entziehen.",
+ "users.view": "Benutzer mit zugewiesenen Rolen sehen."
+} \ No newline at end of file
diff --git a/modules-available/permissionmanager/lang/de/template-tags.json b/modules-available/permissionmanager/lang/de/template-tags.json
index 71bd4075..504ef6d2 100644
--- a/modules-available/permissionmanager/lang/de/template-tags.json
+++ b/modules-available/permissionmanager/lang/de/template-tags.json
@@ -1,24 +1,24 @@
{
- "lang_roles": "Rollen",
- "lang_users": "Nutzer",
- "lang_locations": "Räume",
"lang_addRole": "Rollen erteilen",
- "lang_removeRole": "Rollen entziehen",
- "lang_newRole": "Rolle anlegen",
- "lang_selected": "Ausgewählt",
- "lang_edit": "Bearbeiten",
- "lang_delete": "Löschen",
- "lang_removeCheck": "Sind Sie sich sicher, dass Sie diese Rolle entfernen wollen?",
- "lang_deleteCheck": "Sind Sie sich sicher, dass Sie diese Rolle löschen wollen?",
- "lang_emptyNameWarning": "Der Name der Rolle darf nicht leer sein!",
+ "lang_addRoleHeading": "Neue Rolle hinzuf\u00fcgen",
+ "lang_description": "Beschreibung",
+ "lang_editRoleHeading": "Rolle bearbeiten",
+ "lang_locationAwareDesc": "Berechtigungen mit diesem Symbol k\u00f6nnen auf bestimmte R\u00e4ume\/Orte beschr\u00e4nkt werden. Alle anderen Berechtigungen sind unabh\u00e4ngig von den f\u00fcr diese Rolle ausgew\u00e4hlten Orten.",
+ "lang_locations": "R\u00e4ume",
+ "lang_moduleName": "Rechtemanager",
"lang_name": "Name",
- "lang_cancel": "Abbrechen",
- "lang_save": "Speichern",
- "lang_all": "alle",
- "lang_selected": "ausgewählte",
+ "lang_newRole": "Rolle anlegen",
+ "lang_numAssignedUsers": "Benutzer mit dieser Rolle",
+ "lang_permission": "Berechtigung",
+ "lang_permissionDeniedBody": "Ihnen fehlt eine oder mehrere Berechtigungen, um auf diese Seite oder Funktion zuzugreifen.",
+ "lang_permissionDeniedHeader": "Zugriff verweigert",
"lang_permissions": "Rechte",
- "lang_selectizePlaceholder": "Nach Rollen filtern...",
+ "lang_removeRole": "Rollen entziehen",
+ "lang_roleDeleteConfirm": "Sind Sie sich sicher, dass Sie diese Rolle l\u00f6schen m\u00f6chten? Benutzer, denen diese Rolle zugewiesen ist, werden die entsprechenden Berechtigungen verlieren.",
+ "lang_roles": "Rollen",
"lang_searchPlaceholder": "Nach Rollen suchen...",
- "lang_moduleName": "Rechtemanager",
- "lang_roleEditor": "Rollen Editor"
+ "lang_selected": "ausgew\u00e4hlte",
+ "lang_selectizePlaceholder": "Nach Rollen filtern...",
+ "lang_users": "Nutzer",
+ "lang_view": "Anzeigen"
} \ No newline at end of file
diff --git a/modules-available/permissionmanager/lang/en/permissions.json b/modules-available/permissionmanager/lang/en/permissions.json
new file mode 100644
index 00000000..9f7263db
--- /dev/null
+++ b/modules-available/permissionmanager/lang/en/permissions.json
@@ -0,0 +1,7 @@
+{
+ "locations.view": "See locations with assigned roles.",
+ "roles.edit": "Edit roles.",
+ "roles.view": "Show roles.",
+ "users.edit-roles": "Assign or remove roles from users.",
+ "users.view": "See users with assigned roles."
+} \ No newline at end of file
diff --git a/modules-available/permissionmanager/lang/en/template-tags.json b/modules-available/permissionmanager/lang/en/template-tags.json
index 2d31b294..6f1fa614 100644
--- a/modules-available/permissionmanager/lang/en/template-tags.json
+++ b/modules-available/permissionmanager/lang/en/template-tags.json
@@ -1,24 +1,24 @@
{
- "lang_roles": "Roles",
- "lang_users": "Users",
- "lang_locations": "Locations",
"lang_addRole": "Grant Roles",
- "lang_removeRole": "Revoke Roles",
- "lang_newRole": "New Role",
- "lang_selected": "Selected",
- "lang_edit": "Edit",
- "lang_delete": "Delete",
- "lang_removeCheck": "Are you sure you want to remove this role?",
- "lang_deleteCheck": "Are you sure you want to delete this role?",
- "lang_emptyNameWarning": "Role name can not be empty!",
+ "lang_addRoleHeading": "Add new role",
+ "lang_description": "Description",
+ "lang_editRoleHeading": "Edit role",
+ "lang_locationAwareDesc": "Permissions with this symbol can be restricted to certain locations. All other permissions are independent of the locations selected for this role.",
+ "lang_locations": "Locations",
+ "lang_moduleName": "Permission Manager",
"lang_name": "Name",
- "lang_cancel": "Cancel",
- "lang_save": "Save",
- "lang_all": "all",
- "lang_selected": "selected",
+ "lang_newRole": "New Role",
+ "lang_numAssignedUsers": "Users with this role",
+ "lang_permission": "Permission",
+ "lang_permissionDeniedBody": "You are missing one or more permissions to access this page or functionality.",
+ "lang_permissionDeniedHeader": "Access denied",
"lang_permissions": "Permissions",
- "lang_selectizePlaceholder": "Filter for roles...",
+ "lang_removeRole": "Revoke Roles",
+ "lang_roleDeleteConfirm": "Are you sure you want to delete this role? Users currently assigned to this role will lose the according permissions.",
+ "lang_roles": "Roles",
"lang_searchPlaceholder": "Search for roles...",
- "lang_moduleName": "Permission Manager",
- "lang_roleEditor": "Role Editor"
+ "lang_selected": "selected",
+ "lang_selectizePlaceholder": "Filter for roles...",
+ "lang_users": "Users",
+ "lang_view": "View"
} \ No newline at end of file
diff --git a/modules-available/permissionmanager/page.inc.php b/modules-available/permissionmanager/page.inc.php
index 13d81c6a..462d3163 100644
--- a/modules-available/permissionmanager/page.inc.php
+++ b/modules-available/permissionmanager/page.inc.php
@@ -17,22 +17,38 @@ class Page_PermissionManager extends Page
$action = Request::any('action', 'show', 'string');
if ($action === 'addRoleToUser') {
+ User::assertPermission('users.edit-roles');
$users = Request::post('users', '');
$roles = Request::post('roles', '');
PermissionDbUpdate::addRoleToUser($users, $roles);
} elseif ($action === 'removeRoleFromUser') {
+ User::assertPermission('users.edit-roles');
$users = Request::post('users', '');
$roles = Request::post('roles', '');
PermissionDbUpdate::removeRoleFromUser($users, $roles);
} elseif ($action === 'deleteRole') {
- $id = Request::post('deleteId', false, 'string');
+ User::assertPermission('roles.edit');
+ $id = Request::post('deleteId', false, 'int');
PermissionDbUpdate::deleteRole($id);
} elseif ($action === 'saveRole') {
- $roleID = Request::post("roleid", false);
- $rolename = Request::post("rolename");
- $locations = self::processLocations(Request::post("locations"));
+ User::assertPermission('roles.edit');
+ $roleID = Request::post("roleid", false, 'int');
+ if ($roleID === false) {
+ Message::addError('main.parameter-missing', 'roleid');
+ Util::redirect('?do=permissionmanager');
+ }
+ $roleName = Request::post("rolename", '', 'string');
+ if (empty($roleName)) {
+ Message::addError('main.parameter-empty', 'rolename');
+ Util::redirect('?do=permissionmanager');
+ }
+ $roleDescription = Request::post('roledescription', '', 'string');
+ $locations = self::processLocations(Request::post("locations", [], 'array'));
$permissions = self::processPermissions(Request::post("permissions"));
- PermissionDbUpdate::saveRole($rolename, $locations, $permissions, $roleID);
+ PermissionDbUpdate::saveRole($roleName, $roleDescription, $locations, $permissions, $roleID);
+ }
+ if (Request::isPost()) {
+ Util::redirect('?do=permissionmanager&show=' . Request::get("show", "roles"));
}
}
@@ -41,47 +57,76 @@ class Page_PermissionManager extends Page
*/
protected function doRender()
{
- $show = Request::get("show", "roles");
+ $show = Request::get("show", false, 'string');
+
+ // "Public" page -- nice "permission denied" message
+ if ($show === 'denied') {
+ Render::addTemplate('page-permission-denied', [
+ 'name' => User::getName(),
+ 'permission' => Request::get('permission', false, 'string'),
+ ]);
+ return;
+ }
+
+ if ($show === false) {
+ foreach (['roles', 'users', 'locations'] as $show) {
+ if (User::hasPermission($show . '.*'))
+ break;
+ }
+ }
// switch between tables, but always show menu to switch tables
- if ( $show === 'roles' || $show === 'users' || $show === 'locations' ) {
- // get menu button colors
- $buttonColors = array();
- $buttonColors['rolesButtonClass'] = $show === 'roles' ? 'active' : '';
- $buttonColors['usersButtonClass'] = $show === 'users' ? 'active' : '';
- $buttonColors['locationsButtonClass'] = $show === 'locations' ? 'active' : '';
-
- Render::addtemplate('_page', $buttonColors);
-
- if ($show === "roles") {
- $data = array("roles" => GetPermissionData::getRoles());
- Render::addTemplate('rolestable', $data);
- } elseif ($show === "users") {
- $data = array("user" => GetPermissionData::getUserData(), "roles" => GetPermissionData::getRoles());
- Render::addTemplate('userstable', $data);
- } elseif ($show === "locations") {
- $data = array("location" => GetPermissionData::getLocationData(), "allroles" => GetPermissionData::getRoles());
- Render::addTemplate('locationstable', $data);
+ // get menu button colors
+ $data = array();
+ if ($show === "roleEditor") {
+ $data['groupClass'] = 'btn-group-muted';
+ $data['rolesButtonClass'] = 'active';
+ } else {
+ $data[$show . 'ButtonClass'] = 'active';
+ }
+ Permission::addGlobalTags($data['perms'], null, ['roles.*', 'users.*', 'locations.*']);
+
+ Render::addtemplate('header-menu', $data);
+
+ if ($show === "roles") {
+ User::assertPermission('roles.*');
+ $data = array("roles" => GetPermissionData::getRoles(GetPermissionData::WITH_USER_COUNT));
+ Permission::addGlobalTags($data['perms'], null, ['roles.edit']);
+ Render::addTemplate('rolestable', $data);
+ } elseif ($show === "users") {
+ User::assertPermission('users.*');
+ $data = array("user" => GetPermissionData::getUserData());
+ if (User::hasPermission('users.edit-roles')) {
+ $data['allroles'] = GetPermissionData::getRoles();
}
+ Permission::addGlobalTags($data['perms'], null, ['users.edit-roles']);
+ Render::addTemplate('role-filter-selectize', $data);
+ Render::addTemplate('userstable', $data);
+ } elseif ($show === "locations") {
+ User::assertPermission('locations.*');
+ $data = array("location" => GetPermissionData::getLocationData(), "allroles" => GetPermissionData::getRoles());
+ Render::addTemplate('role-filter-selectize', $data);
+ Render::addTemplate('locationstable', $data);
} elseif ($show === "roleEditor") {
- $data = array("cancelShow" => Request::get("cancel", "roles"));
+ User::assertPermission('roles.*');
+ $data = array("cancelShow" => Request::get("cancel", "roles", 'string'));
+ Permission::addGlobalTags($data['perms'], null, ['roles.edit']);
$selectedPermissions = array();
$selectedLocations = array();
- $roleid = Request::get("roleid", false);
- if ($roleid) {
- $roleData = GetPermissionData::getRoleData($roleid);
- $data["roleid"] = $roleid;
- $data["rolename"] = $roleData["rolename"];
- $selectedPermissions = $roleData["permissions"];
- $selectedLocations = $roleData["locations"];
+ $roleid = Request::get("roleid", false, 'int');
+ if ($roleid !== false) {
+ $data += GetPermissionData::getRoleData($roleid);
+ $selectedPermissions = $data["permissions"];
+ $selectedLocations = $data["locations"];
}
- $data["permissionHTML"] = self::generatePermissionHTML(PermissionUtil::getPermissions(), $selectedPermissions);
- $data["locationHTML"] = self::generateLocationHTML(Location::getTree(), $selectedLocations);
+ $data["permissionHTML"] = self::generatePermissionHTML(PermissionUtil::getPermissions(), $selectedPermissions,
+ false, '', ['perms' => $data['perms']]);
+ $data["locationHTML"] = self::generateLocationHTML(Location::getTree(), $selectedLocations,
+ $roleid === false, true, ['perms' => $data['perms']]);
Render::addTemplate('roleeditor', $data);
-
}
}
@@ -90,36 +135,57 @@ class Page_PermissionManager extends Page
*
* @param array $permissions the permission tree
* @param array $selectedPermissions permissions that should be preselected
- * @param array $selectAll true if all pemrissions should be preselected, false if only those in $selectedPermissions
- * @param array $permString the prefix permission string with which all permissions in the permission tree should start
+ * @param bool $selectAll true if all permissions should be preselected, false if only those in $selectedPermissions
+ * @param string $permString the prefix permission string with which all permissions in the permission tree should start
* @return string generated html code
*/
- private static function generatePermissionHTML($permissions, $selectedPermissions = array(), $selectAll = false, $permString = "")
+ private static function generatePermissionHTML($permissions, $selectedPermissions = array(), $selectAll = false, $permString = "", $tags = [])
{
$res = "";
$toplevel = $permString == "";
- if ($toplevel && in_array("*", $selectedPermissions)) $selectAll = true;
+ if ($toplevel && in_array("*", $selectedPermissions)) {
+ $selectAll = true;
+ }
foreach ($permissions as $k => $v) {
- $leaf = !is_array($v);
- $nextPermString = $permString ? $permString.".".$k : $k;
- $id = $leaf ? $nextPermString : $nextPermString.".*";
- $selected = $selectAll || in_array($id, $selectedPermissions);
- $res .= Render::parse("treenode",
- array("id" => $id,
- "name" => $toplevel ? Module::get($k)->getDisplayName() : $k,
- "toplevel" => $toplevel,
- "checkboxname" => "permissions",
- "selected" => $selected,
- "HTML" => $leaf ? "" : self::generatePermissionHTML($v, $selectedPermissions, $selected, $nextPermString),
- "description" => $leaf ? $v : ""));
+ $selected = $selectAll;
+ $nextPermString = $permString ? $permString . "." . $k : $k;
+ if ($toplevel) {
+ $displayName = Module::get($k)->getDisplayName();
+ } else {
+ $displayName = $k;
+ }
+ do {
+ $leaf = isset($v['isLeaf']) && $v['isLeaf'];
+ $id = $leaf ? $nextPermString : $nextPermString . ".*";
+ $selected = $selected || in_array($id, $selectedPermissions);
+ if ($leaf || count($v) !== 1)
+ break;
+ reset($v);
+ $k = key($v);
+ $v = $v[$k];
+ $nextPermString .= '.' . $k;
+ $displayName .= '.' . $k;
+ } while (true);
+ $data = array(
+ "id" => $id,
+ "name" => $displayName,
+ "toplevel" => $toplevel,
+ "checkboxname" => "permissions",
+ "selected" => $selected,
+ "HTML" => $leaf ? "" : self::generatePermissionHTML($v, $selectedPermissions, $selected, $nextPermString, $tags),
+ );
+ if ($leaf) {
+ $data += $v;
+ }
+ $res .= Render::parse("treenode", $data + $tags);
}
if ($toplevel) {
$res = Render::parse("treepanel",
array("id" => "*",
- "name" => Dictionary::translateFile("template-tags", "lang_permissions"),
- "checkboxname" => "permissions",
- "selected" => $selectAll,
- "HTML" => $res));
+ "name" => Dictionary::translateFile("template-tags", "lang_permissions"),
+ "checkboxname" => "permissions",
+ "selected" => $selectAll,
+ "HTML" => $res) + $tags);
}
return $res;
}
@@ -133,28 +199,31 @@ class Page_PermissionManager extends Page
* @param array $toplevel true if the location tree are the children of the root location, false if not
* @return string generated html code
*/
- private static function generateLocationHTML($locations, $selectedLocations = array(), $selectAll = false, $toplevel = true)
+ private static function generateLocationHTML($locations, $selectedLocations = array(), $selectAll = false, $toplevel = true, $tags = [])
{
$res = "";
- if ($toplevel && in_array(0, $selectedLocations)) $selectAll = true;
+ if ($toplevel && in_array(0, $selectedLocations)) {
+ $selectAll = true;
+ }
foreach ($locations as $location) {
$selected = $selectAll || in_array($location["locationid"], $selectedLocations);
$res .= Render::parse("treenode",
- array("id" => $location["locationid"],
- "name" => $location["locationname"],
- "toplevel" => $toplevel,
- "checkboxname" => "locations",
- "selected" => $selected,
- "HTML" => array_key_exists("children", $location) ?
- self::generateLocationHTML($location["children"], $selectedLocations, $selected, false) : ""));
+ array("id" => $location["locationid"],
+ "name" => $location["locationname"],
+ "toplevel" => $toplevel,
+ "checkboxname" => "locations",
+ "selected" => $selected,
+ "HTML" => array_key_exists("children", $location) ?
+ self::generateLocationHTML($location["children"], $selectedLocations, $selected, false, $tags) : "")
+ + $tags);
}
if ($toplevel) {
$res = Render::parse("treepanel",
array("id" => 0,
- "name" => Dictionary::translateFile("template-tags", "lang_locations"),
- "checkboxname" => "locations",
- "selected" => $selectAll,
- "HTML" => $res));
+ "name" => Dictionary::translateFile("template-tags", "lang_locations"),
+ "checkboxname" => "locations",
+ "selected" => $selectAll,
+ "HTML" => $res) + $tags);
}
return $res;
}
@@ -167,12 +236,14 @@ class Page_PermissionManager extends Page
*/
private static function processLocations($locations)
{
- if (in_array(0, $locations)) return array(NULL);
+ if (in_array(0, $locations))
+ return array(null);
$result = array();
foreach ($locations as $location) {
$rootchain = array_reverse(Location::getLocationRootChain($location));
foreach ($rootchain as $l) {
- if (in_array($l, $result)) break;
+ if (in_array($l, $result))
+ break;
if (in_array($l, $locations)) {
$result[] = $l;
break;
@@ -190,7 +261,8 @@ class Page_PermissionManager extends Page
*/
private static function processPermissions($permissions)
{
- if (in_array("*", $permissions)) return array("*");
+ if (in_array("*", $permissions))
+ return array("*");
$result = array();
foreach ($permissions as $permission) {
$x =& $result;
@@ -213,10 +285,10 @@ class Page_PermissionManager extends Page
foreach ($permissions as $permission => $a) {
if (is_array($a)) {
if (array_key_exists("*", $a)) {
- $result[] = $permission.".*";
+ $result[] = $permission . ".*";
} else {
foreach (self::extractPermissions($a) as $subPermission) {
- $result[] = $permission.".".$subPermission;
+ $result[] = $permission . "." . $subPermission;
}
}
} else {
diff --git a/modules-available/permissionmanager/permissions/permissions.json b/modules-available/permissionmanager/permissions/permissions.json
new file mode 100644
index 00000000..3981a2c3
--- /dev/null
+++ b/modules-available/permissionmanager/permissions/permissions.json
@@ -0,0 +1,17 @@
+{
+ "roles.view": {
+ "location-aware": false
+ },
+ "roles.edit": {
+ "location-aware": false
+ },
+ "users.view": {
+ "location-aware": false
+ },
+ "users.edit-roles": {
+ "location-aware": false
+ },
+ "locations.view": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/permissionmanager/style.css b/modules-available/permissionmanager/style.css
index 49d631a8..dca38eeb 100644
--- a/modules-available/permissionmanager/style.css
+++ b/modules-available/permissionmanager/style.css
@@ -1,82 +1,46 @@
-#switchForm {
- text-align: center;
- margin-bottom: 50px;
-}
-
-#saveButton {
- margin-left: 10px;
-}
-
-#rolename {
- width: 200px;
- display: inline-block;
- margin-left: 10px;
-}
-
-.missingInput {
- border-color: rgba(255, 0, 0, 0.8);
- box-shadow: 0 1px 1px rgba(255, 0, 0, 0.075) inset, 0 0 8px rgba(255, 0, 0, 0.6);
-}
-
.table {
margin-top: 20px;
}
-.table > tbody > tr > td {
- vertical-align: middle;
- height: 50px;
-}
-
.scrollingTable {
height: 500px;
overflow: auto;
}
-.customSpanMargin {
+/* vcenter .label in table cell */
+td > .label {
display: inline-block;
- margin-top: 2px;
- margin-bottom: 2px;
+ margin: 2px 0;
}
-.panel-primary > .panel-heading {
- background-image: none;
+/* lists in tree view: hide bullet points, first entry bold, ... */
+.tree-container ul {
+ list-style-type: none;
}
-.panel{
- margin-bottom: 20px;
+.tree-container > ul {
+ display: inline-block;
+ width: 100%;
+ padding: 0;
}
-.selectize-input {
- overflow: visible;
-}
-
-
-.tree-container .selected {
- background-color: rgba(0, 182, 41, 0.23);
+.tree-container > ul > li > div > label {
+ font-weight: bold;
}
+/* number of columns in tree view depending on screen size */
.tree-container {
-moz-column-gap: 20px;
-webkit-column-gap: 20px;
column-gap: 20px;
+ -moz-column-count: 1;
+ -webkit-column-count: 1;
+ column-count: 1;
+ padding-left: 20px;
+ padding-right: 20px;
}
-
-.tree-container > ul {
- display: inline-block;
- width: 100%;
- padding: 0;
-}
-
-@media (max-width: 767px) {
- .tree-container {
- -moz-column-count: 1;
- -webkit-column-count: 1;
- column-count: 1;
- }
-}
-
-@media (min-width: 768px) and (max-width: 991px) {
+@media (min-width: 768px) {
.tree-container {
-moz-column-count: 2;
-webkit-column-count: 2;
@@ -92,6 +56,11 @@
}
}
-ul {
- list-style-type: none;
-} \ No newline at end of file
+.btn-group-muted > button {
+ color: #aaa;
+}
+
+h1 span.glyphicon {
+ top: 9px;
+}
+
diff --git a/modules-available/permissionmanager/templates/_page.html b/modules-available/permissionmanager/templates/_page.html
deleted file mode 100644
index 4140ce78..00000000
--- a/modules-available/permissionmanager/templates/_page.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<div class="row">
- <div class="col-md-12" style="margin-bottom: 0;">
- <div class='page-header'>
- <div class='pull-right'>
- <form id="switchForm" method="GET" action="?do=permissionmanager">
- <input type="hidden" name="do" value="permissionmanager">
-
- <div class="btn-group">
- <button class="btn btn-default {{rolesButtonClass}}" type="submit" name="show" value="roles">
- <span class="glyphicon glyphicon-education"></span>
- {{lang_roles}}
- </button>
-
- <button class="btn btn-default {{usersButtonClass}}" type="submit" name="show" value="users">
- <span class="glyphicon glyphicon-user"></span>
- {{lang_users}}
- </button>
-
- <button class="btn btn-default {{locationsButtonClass}}" type="submit" name="show" value="locations">
- <span class="glyphicon glyphicon-home"></span>
- {{lang_locations}}
- </button>
- </div>
- </form>
- </div>
- <h1>{{lang_moduleName}}</h1>
- </div>
- </div>
-</div> \ No newline at end of file
diff --git a/modules-available/permissionmanager/templates/header-menu.html b/modules-available/permissionmanager/templates/header-menu.html
new file mode 100644
index 00000000..91bfa3af
--- /dev/null
+++ b/modules-available/permissionmanager/templates/header-menu.html
@@ -0,0 +1,25 @@
+<div class='page-header'>
+ <div class='pull-right'>
+ <form method="GET">
+ <input type="hidden" name="do" value="permissionmanager">
+
+ <div class="btn-group {{groupClass}}">
+ <button class="btn btn-default {{rolesButtonClass}}" type="submit" name="show" value="roles" {{perms.roles.disabled}}>
+ <span class="glyphicon glyphicon-education"></span>
+ {{lang_roles}}
+ </button>
+
+ <button class="btn btn-default {{usersButtonClass}}" type="submit" name="show" value="users" {{perms.users.disabled}}>
+ <span class="glyphicon glyphicon-user"></span>
+ {{lang_users}}
+ </button>
+
+ <button class="btn btn-default {{locationsButtonClass}}" type="submit" name="show" value="locations" {{perms.locations.disabled}}>
+ <span class="glyphicon glyphicon-home"></span>
+ {{lang_locations}}
+ </button>
+ </div>
+ </form>
+ </div>
+ <h1>{{lang_moduleName}}</h1>
+</div> \ No newline at end of file
diff --git a/modules-available/permissionmanager/templates/locationstable.html b/modules-available/permissionmanager/templates/locationstable.html
index 153258fe..35058387 100644
--- a/modules-available/permissionmanager/templates/locationstable.html
+++ b/modules-available/permissionmanager/templates/locationstable.html
@@ -1,37 +1,21 @@
-<div class="row">
- <div class="col-md-4"></div>
- <div class="col-md-4">
- <select multiple name="roles[]" id="select-role">
- <option value>{{lang_selectizePlaceholder}}</option>
- {{#allroles}}
- <option value="{{roleid}}">{{rolename}}</option>
- {{/allroles}}
- </select>
- </div>
-</div>
+<table id="locationsTable" class="table table-condensed table-hover dataTable">
+ <thead>
+ <tr>
+ <th>{{lang_locations}}</th>
+ <th class="slx-smallcol">{{lang_roles}}</th>
+ </tr>
+ </thead>
-<div class="row">
- <div class="col-md-12">
- <table id="locationsTable" class="table table-condensed table-hover stupidtable dataTable">
- <thead>
- <tr>
- <th data-sort="string">{{lang_locations}}</th>
- <th>{{lang_roles}}</th>
- </tr>
- </thead>
-
- <tbody>
- {{#location}}
- <tr data-selectizeCount='0'>
- <td>{{locationpad}} {{locationname}}</td>
- <td>
- {{#roles}}
- <a href="?do=permissionmanager&show=roleEditor&cancel=locations&roleid={{roleid}}" class="label label-default customSpanMargin roleid-{{roleid}}">{{rolename}}</a>
- {{/roles}}
- </td>
- </tr>
- {{/location}}
- </tbody>
- </table>
- </div>
-</div> \ No newline at end of file
+ <tbody>
+ {{#location}}
+ <tr class="{{#roles}}roleid-{{roleid}} {{/roles}}">
+ <td>{{locationpad}} {{locationname}}</td>
+ <td class="slx-smallcol">
+ {{#roles}}
+ <a href="?do=permissionmanager&show=roleEditor&cancel=locations&roleid={{roleid}}" class="label label-default customSpanMargin">{{rolename}}</a>
+ {{/roles}}
+ </td>
+ </tr>
+ {{/location}}
+ </tbody>
+</table> \ No newline at end of file
diff --git a/modules-available/permissionmanager/templates/page-permission-denied.html b/modules-available/permissionmanager/templates/page-permission-denied.html
new file mode 100644
index 00000000..cc357a0b
--- /dev/null
+++ b/modules-available/permissionmanager/templates/page-permission-denied.html
@@ -0,0 +1,21 @@
+<br><br>
+<div class="jumbotron">
+ <h1>
+ <span class="text-danger">
+ <span class="glyphicon glyphicon-ban-circle"></span>
+ {{lang_permissionDeniedHeader}}
+ </span>
+ </h1>
+ <br><br>
+ <p>
+ {{lang_permissionDeniedBody}}
+ </p>
+ {{#permission}}
+ <div>
+ {{lang_permission}}: <b>{{permission}}</b>
+ </div>
+ {{/permission}}
+ <div>
+ {{lang_user}}: <b>{{name}}</b>
+ </div>
+</div>
diff --git a/modules-available/permissionmanager/templates/role-filter-selectize.html b/modules-available/permissionmanager/templates/role-filter-selectize.html
new file mode 100644
index 00000000..ceadec75
--- /dev/null
+++ b/modules-available/permissionmanager/templates/role-filter-selectize.html
@@ -0,0 +1,6 @@
+<select multiple id="select-role">
+ <option value>{{lang_selectizePlaceholder}}</option>
+ {{#allroles}}
+ <option value="{{roleid}}">{{rolename}}</option>
+ {{/allroles}}
+</select> \ No newline at end of file
diff --git a/modules-available/permissionmanager/templates/roleeditor.html b/modules-available/permissionmanager/templates/roleeditor.html
index 871fd0cc..c464c1fc 100644
--- a/modules-available/permissionmanager/templates/roleeditor.html
+++ b/modules-available/permissionmanager/templates/roleeditor.html
@@ -1,36 +1,55 @@
-<h1>{{lang_roleEditor}}</h1>
+<h2>
+ {{#roleid}}
+ {{lang_editRoleHeading}}
+ {{/roleid}}
+ {{^roleid}}
+ {{lang_addRoleHeading}}
+ {{/roleid}}
+</h2>
+
<form method="post" action="?do=permissionmanager">
<input type="hidden" name="action" value="saveRole">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="roleid" value="{{roleid}}">
- <div class="row">
- <div class="col-md-12" style="margin-bottom: 20px;">
- <ul class="nav nav-tabs text-center" role="tablist">
- <li role="presentation" class="active"><a href="#permissions" role="tab" data-toggle="tab">{{lang_permissions}}</a></li>
- <li role="presentation"><a href="#locations" role="tab" data-toggle="tab">{{lang_locations}}</a></li>
- <li style="float: none; display: inline-block">
- <label for="rolename">{{lang_name}}:</label>
- <input id="rolename" name="rolename" value="{{rolename}}" type="text" class="form-control">
- </li>
- <li style="float: right;">
- <span><a href="?do=permissionmanager&show={{cancelShow}}" id="cancelButton" class="btn btn-default">{{lang_cancel}}</a></span>
- <button type="submit" id="saveButton" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
- </li>
- </ul>
- </div>
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ <label for="rolename">{{lang_name}}</label>
+ </span>
+ <input id="rolename" name="rolename" value="{{rolename}}" type="text" class="form-control" required>
</div>
- <div class="row" style="margin-bottom: 20px;">
- <div class="col-md-12">
- <div class="tab-content">
- <div role="tabpanel" class="tab-pane active" id="permissions">
- {{{permissionHTML}}}
- </div>
- <div role="tabpanel" class="tab-pane" id="locations">
- {{{locationHTML}}}
+ <div class="input-group">
+ <span class="input-group-addon slx-ga">
+ <label for="roledescription">{{lang_description}}</label>
+ </span>
+ <input id="roledescription" name="roledescription" value="{{roledescription}}" type="text" class="form-control">
+ </div>
+ <br>
+
+ <div class="pull-right">
+ <a href="?do=permissionmanager&amp;show={{cancelShow}}" class="btn btn-default">{{lang_cancel}}</a>
+ <button type="submit" class="btn btn-primary" {{perms.roles.edit.disabled}}>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ <ul class="nav nav-tabs text-center" role="tablist">
+ <li role="presentation" class="active"><a href="#permissions" role="tab" data-toggle="tab">{{lang_permissions}}</a></li>
+ <li role="presentation"><a href="#locations" role="tab" data-toggle="tab">{{lang_locations}}</a></li>
+ </ul>
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane active" id="permissions">
+ {{{permissionHTML}}}
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <span class="glyphicon glyphicon-home text-muted"></span>&emsp;
+ {{lang_locationAwareDesc}}
</div>
</div>
</div>
+ <div role="tabpanel" class="tab-pane" id="locations">
+ {{{locationHTML}}}
+ </div>
</div>
</form>
@@ -39,16 +58,14 @@
document.addEventListener("DOMContentLoaded", function () {
- $(".tree-panel input[type=checkbox]").change(function () {
- var checked = $(this).prop("checked");
- var parent = $(this).parent().parent();
- if (parent.hasClass("panel-heading")) parent = parent.parent();
+ $(".tree-container input[type=checkbox]").change(function () {
+ // (Un)Mark all sub-elements when changing a checkbox in the panel body
+ var $this = $(this);
+ var checked = $this.prop("checked");
+ $this.closest('li').find("input[type=checkbox]").prop("checked", checked);
- var checkboxes = parent.find("input[type=checkbox]");
- if (checked) {
- checkboxes.prop("checked", true);
- } else {
- checkboxes.prop("checked", false);
+ if (!checked) {
+ var parent = $(this).parent().parent();
while (!parent.hasClass("tree-panel")) {
parent = parent.parent().parent();
if (parent.hasClass("tree-container")) parent = parent.parent().parent();
@@ -56,14 +73,11 @@
}
}
});
-
- $('form').submit(function () {
- var input = $("#rolename");
- var name = $.trim(input.val());
- if (!name) {
- input.addClass("missingInput");
- return false;
- }
+ $("input.master-checkbox").change(function () {
+ // (Un)Mark everything within the panel when the master checkbox on top is clicked
+ var $this = $(this);
+ var checked = $this.prop("checked");
+ $this.closest('.tree-panel').find("input[type=checkbox]").prop("checked", checked);
});
$('[data-toggle="tooltip"]').tooltip({
diff --git a/modules-available/permissionmanager/templates/rolestable.html b/modules-available/permissionmanager/templates/rolestable.html
index b121a9e0..d520db33 100644
--- a/modules-available/permissionmanager/templates/rolestable.html
+++ b/modules-available/permissionmanager/templates/rolestable.html
@@ -1,15 +1,8 @@
<form method="post" action="?do=permissionmanager">
<input type="hidden" name="token" value="{{token}}">
- <div class="row">
- <div class="col-md-4">
- </div>
- <div class="col-md-4">
- <input type="text" class="form-control" id="roleNameSearchField" onkeyup="searchFieldFunction()" placeholder="{{lang_searchPlaceholder}}">
- </div>
- <div class="col-md-4 text-right">
- <a href="?do=permissionmanager&show=roleEditor" class="btn btn-success"><span class="glyphicon glyphicon-plus"></span> {{lang_newRole}}</a>
- </div>
+ <div>
+ <input type="text" class="form-control" id="roleNameSearchField" onkeyup="searchFieldFunction()" placeholder="{{lang_searchPlaceholder}}">
</div>
<div class="row">
@@ -18,8 +11,16 @@
<thead>
<tr>
<th data-sort="string">{{lang_roles}}</th>
- <th class="text-center">{{lang_edit}}</th>
- <th class="text-center">{{lang_delete}}</th>
+ <th data-sort="string">{{lang_description}}</th>
+ <th class="text-center slx-smallcol">
+ {{#perms.roles.edit.disabled}}
+ {{lang_view}}
+ {{/perms.roles.edit.disabled}}
+ {{^perms.roles.edit.disabled}}
+ {{lang_edit}}
+ {{/perms.roles.edit.disabled}}
+ </th>
+ <th class="text-center slx-smallcol">{{lang_delete}}</th>
</tr>
</thead>
@@ -27,11 +28,14 @@
{{#roles}}
<tr>
<td class="rolename">{{rolename}}</td>
+ <td class="text-muted"><table class="slx-ellipsis"><tr><td>{{roledescription}}</td></tr></table></td>
<td class="text-center">
- <a class="btn btn-xs btn-primary" href="?do=permissionmanager&show=roleEditor&roleid={{roleid}}"><span class="glyphicon glyphicon-edit"></span></a>
+ <a class="btn btn-xs btn-primary" href="?do=permissionmanager&amp;show=roleEditor&amp;roleid={{roleid}}"><span class="glyphicon glyphicon-edit"></span></a>
</td>
<td class="text-center">
- <a class="btn btn-xs btn-danger" href="#deleteModal" data-toggle="modal" data-target="#deleteModal" onclick="deleteRole('{{roleid}}')"><span class="glyphicon glyphicon-trash"></span></a>
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="deleteRole('{{roleid}}', '{{users}}')" {{perms.roles.edit.disabled}}>
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
</td>
</tr>
{{/roles}}
@@ -40,7 +44,6 @@
</div>
</div>
-
<!-- Modals -->
<div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
@@ -50,10 +53,11 @@
<h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
</div>
<div class="modal-body">
- {{lang_deleteCheck}}
+ <p>{{lang_roleDeleteConfirm}}</p>
+ {{lang_numAssignedUsers}}: <span id="delete-role-users"></span>
</div>
<div class="modal-footer">
- <input type="hidden" id="deleteId" name="deleteId" value=""/>
+ <input type="hidden" id="delete-role-id" name="deleteId" value="">
<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
<button type="submit" name="action" value="deleteRole" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
</div>
@@ -63,9 +67,14 @@
</form>
+<div class="text-right">
+ <a href="?do=permissionmanager&amp;show=roleEditor" class="btn btn-success {{perms.roles.edit.disabled}}"><span class="glyphicon glyphicon-plus"></span> {{lang_newRole}}</a>
+</div>
+
<script>
- function deleteRole($roleid) {
- $(".modal-footer #deleteId").val($roleid);
+ function deleteRole(roleid, users) {
+ $("#delete-role-id").val(roleid);
+ $("#delete-role-users").text(users);
}
function searchFieldFunction() {
diff --git a/modules-available/permissionmanager/templates/treenode.html b/modules-available/permissionmanager/templates/treenode.html
index ced973ca..f8ee3df5 100644
--- a/modules-available/permissionmanager/templates/treenode.html
+++ b/modules-available/permissionmanager/templates/treenode.html
@@ -1,11 +1,14 @@
{{#toplevel}}<ul>{{/toplevel}}
- <li title="{{description}}" data-toggle="tooltip" data-placement="left">
- <div class='checkbox'>
- <input id="{{id}}" name="{{checkboxname}}[]" value="{{id}}" type="checkbox" class="form-control" {{#selected}}checked{{/selected}}>
- <label for="{{id}}">{{#toplevel}}<b>{{/toplevel}}{{name}}{{#toplevel}}</b>{{/toplevel}}</label>
- </div>
- <ul>
- {{{HTML}}}
- </ul>
- </li>
-{{#toplevel}}</ul>{{/toplevel}}
+<li {{#description}}title="{{description}}" data-toggle="tooltip" data-placement="left"{{/description}}>
+ <div class='checkbox'>
+ <input id="{{id}}" name="{{checkboxname}}[]" value="{{id}}" type="checkbox" {{#selected}}checked{{/selected}} {{edit_disabled}} {{perms.roles.edit.disabled}}>
+ <label for="{{id}}">
+ {{name}}
+ {{#location-aware}}<span class="glyphicon glyphicon-home text-muted"></span>{{/location-aware}}
+ </label>
+ </div>
+ <ul>
+ {{{HTML}}}
+ </ul>
+</li>
+{{#toplevel}}</ul>{{/toplevel}} \ No newline at end of file
diff --git a/modules-available/permissionmanager/templates/treepanel.html b/modules-available/permissionmanager/templates/treepanel.html
index 6f358825..eccecb58 100644
--- a/modules-available/permissionmanager/templates/treepanel.html
+++ b/modules-available/permissionmanager/templates/treepanel.html
@@ -1,12 +1,12 @@
<div class="panel panel-primary tree-panel">
<div class="panel-heading">
<div class="checkbox">
- <input id="{{id}}" name="{{checkboxname}}[]" value="{{id}}" type="checkbox" class="form-control" {{#selected}}checked{{/selected}}>
+ <input id="{{id}}" name="{{checkboxname}}[]" value="{{id}}" type="checkbox" class="master-checkbox" {{#selected}}checked{{/selected}} {{perms.roles.edit.disabled}}>
<label for="{{id}}">{{name}}</label>
</div>
</div>
<div class="panel-body">
- <div class="tree-container" style="padding-left: 20px; padding-right: 20px;">
+ <div class="tree-container">
{{{HTML}}}
</div>
</div>
diff --git a/modules-available/permissionmanager/templates/userstable.html b/modules-available/permissionmanager/templates/userstable.html
index bb0e228e..4cda2b1b 100644
--- a/modules-available/permissionmanager/templates/userstable.html
+++ b/modules-available/permissionmanager/templates/userstable.html
@@ -2,40 +2,23 @@
<input type="hidden" name="token" value="{{token}}">
<div class="row">
- <div class="col-md-4">
- </div>
- <div class="col-md-4">
- <select multiple name="roles[]" id="select-role">
- <option value>{{lang_selectizePlaceholder}}</option>
- {{#roles}}
- <option value="{{roleid}}">{{rolename}}</option>
- {{/roles}}
- </select>
- </div>
- <div class="col-md-4 text-right">
- <button class="roleButtons btn btn-success" type="button" data-toggle="modal" data-target="#addRoleToUserModal" disabled><span class="glyphicon glyphicon-share-alt"></span> {{lang_addRole}}</button>
- <button class="roleButtons btn btn-danger" type="button" data-toggle="modal" data-target="#removeRoleFromUserModal" disabled><span class="glyphicon glyphicon-remove-circle"></span> {{lang_removeRole}}</button>
- </div>
- </div>
-
- <div class="row">
<div class="col-md-12">
<table id="usersTable" class="table table-condensed table-hover stupidtable dataTable">
<thead>
<tr>
<th data-sort="string">{{lang_users}}</th>
- <th>{{lang_roles}}</th>
- <th data-sort="int" data-sort-default="desc">{{lang_selected}}</th>
+ <th class="slx-smallcol">{{lang_roles}}</th>
+ <th class="slx-smallcol" data-sort="int" data-sort-default="desc">{{lang_selected}}</th>
</tr>
</thead>
<tbody>
{{#user}}
- <tr data-selectizeCount='0'>
+ <tr class="{{#roles}}roleid-{{roleid}} {{/roles}}">
<td>{{username}}</td>
- <td>
+ <td class="slx-smallcol">
{{#roles}}
- <a href="?do=permissionmanager&show=roleEditor&cancel=users&roleid={{roleid}}" class="label label-default customSpanMargin roleid-{{roleid}}">{{rolename}}</a>
+ <a href="?do=permissionmanager&show=roleEditor&cancel=users&roleid={{roleid}}" class="label label-default customSpanMargin">{{rolename}}</a>
{{/roles}}
</td>
<td data-sort-value="0">
@@ -71,7 +54,7 @@
</thead>
<tbody>
- {{#roles}}
+ {{#allroles}}
<tr>
<td>{{rolename}}</td>
<td data-sort-value="0">
@@ -81,7 +64,7 @@
</div>
</td>
</tr>
- {{/roles}}
+ {{/allroles}}
</tbody>
</table>
</div>
@@ -114,7 +97,7 @@
</thead>
<tbody>
- {{#roles}}
+ {{#allroles}}
<tr>
<td>{{rolename}}</td>
<td data-sort-value="0">
@@ -124,7 +107,7 @@
</div>
</td>
</tr>
- {{/roles}}
+ {{/allroles}}
</tbody>
</table>
</div>
@@ -139,6 +122,11 @@
</div>
</form>
+<div class="text-right">
+ <button class="roleButtons btn btn-success" type="button" data-toggle="modal" data-target="#addRoleToUserModal" disabled><span class="glyphicon glyphicon-share-alt"></span> {{lang_addRole}}</button>
+ <button class="roleButtons btn btn-danger" type="button" data-toggle="modal" data-target="#removeRoleFromUserModal" disabled><span class="glyphicon glyphicon-remove-circle"></span> {{lang_removeRole}}</button>
+</div>
+
<script>
selectedUsersCounter = 0;
selectedAddRolesCounter = 0;
diff --git a/modules-available/rebootcontrol/config.json b/modules-available/rebootcontrol/config.json
index d8ab5868..43d2c28f 100644
--- a/modules-available/rebootcontrol/config.json
+++ b/modules-available/rebootcontrol/config.json
@@ -1,4 +1,7 @@
{
- "category":"main.beta",
- "dependencies": [ "locations", "js_stupidtable" ]
-}
+ "category": "main.beta",
+ "dependencies": [
+ "locations",
+ "js_stupidtable"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php
index 789552cd..ec4b84ed 100644
--- a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php
+++ b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php
@@ -3,28 +3,83 @@
class RebootControl
{
+ const KEY_TASKLIST = 'rebootcontrol.tasklist';
+
+ const REBOOT = 'REBOOT';
+ const KEXEC_REBOOT = 'KEXEC_REBOOT';
+ const SHUTDOWN = 'SHUTDOWN';
+
/**
* @param string[] $uuids List of machineuuids to reboot
+ * @param bool $kexec whether to trigger kexec-reboot instead of full BIOS cycle
* @return false|array task struct for the reboot job
*/
- public static function reboot($uuids)
+ public static function reboot($uuids, $kexec = false)
{
$list = RebootQueries::getMachinesByUuid($uuids);
if (empty($list))
return false;
- return self::execute($list, false, 0, 0);
+ return self::execute($list, $kexec ? RebootControl::KEXEC_REBOOT : RebootControl::REBOOT, 0, 0);
}
- public static function execute($list, $shutdown, $minutes, $locationId)
+ /**
+ * @param array $list list of clients containing each keys 'machineuuid' and 'clientip'
+ * @param string $mode reboot mode: RebootControl::REBOOT ::KEXEC_REBOOT or ::SHUTDOWN
+ * @param int $minutes delay in minutes for action
+ * @param int $locationId meta data only: locationId of clients
+ * @return array|false the task, or false if it could not be started
+ */
+ public static function execute($list, $mode, $minutes, $locationId)
{
- return Taskmanager::submit("RemoteReboot", array(
+ $task = Taskmanager::submit("RemoteReboot", array(
"clients" => $list,
- "shutdown" => $shutdown,
+ "mode" => $mode,
"minutes" => $minutes,
"locationId" => $locationId,
"sshkey" => SSHKey::getPrivateKey(),
"port" => 9922, // Hard-coded, must match mgmt-sshd module
));
+ if (!Taskmanager::isFailed($task)) {
+ Property::addToList(RebootControl::KEY_TASKLIST, $locationId . '/' . $task["id"], 60 * 24);
+ }
+ return $task;
+ }
+
+ /**
+ * @param int[]|null $locations filter by these locations
+ * @return array list of active tasks for reboots/shutdowns.
+ */
+ public static function getActiveTasks($locations = null)
+ {
+ if (is_array($locations) && in_array(0,$locations)) {
+ $locations = null;
+ }
+ $list = Property::getList(RebootControl::KEY_TASKLIST);
+ $return = [];
+ foreach ($list as $entry) {
+ $p = explode('/', $entry, 2);
+ if (count($p) !== 2) {
+ Property::removeFromList(RebootControl::KEY_TASKLIST, $entry);
+ continue;
+ }
+ if (is_array($locations) && !in_array($p[0], $locations)) // Ignore
+ continue;
+ $id = $p[1];
+ $task = Taskmanager::status($id);
+ if (!Taskmanager::isTask($task)) {
+ Property::removeFromList(RebootControl::KEY_TASKLIST, $entry);
+ continue;
+ }
+ $return[] = [
+ 'taskId' => $task['id'],
+ 'locationId' => $task['data']['locationId'],
+ 'time' => $task['data']['time'],
+ 'mode' => $task['data']['mode'],
+ 'clientCount' => count($task['data']['clients']),
+ 'status' => $task['statusCode'],
+ ];
+ }
+ return $return;
}
} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/inc/rebootqueries.inc.php b/modules-available/rebootcontrol/inc/rebootqueries.inc.php
index 3dc3183f..063b36e4 100644
--- a/modules-available/rebootcontrol/inc/rebootqueries.inc.php
+++ b/modules-available/rebootcontrol/inc/rebootqueries.inc.php
@@ -44,13 +44,13 @@ class RebootQueries
/**
* Get machines by list of UUIDs
* @param string[] $list list of system UUIDs
- * @return array list of machines with machineuuid, clientip and locationid
+ * @return array list of machines with machineuuid, hostname, clientip, state and locationid
*/
public static function getMachinesByUuid($list)
{
if (empty($list))
return array();
- $res = Database::simpleQuery("SELECT machineuuid, clientip, locationid FROM machine
+ $res = Database::simpleQuery("SELECT machineuuid, hostname, clientip, state, locationid FROM machine
WHERE machineuuid IN (:list)", compact('list'));
return $res->fetchAll(PDO::FETCH_ASSOC);
}
diff --git a/modules-available/rebootcontrol/lang/de/module.json b/modules-available/rebootcontrol/lang/de/module.json
index 03196610..1f325354 100644
--- a/modules-available/rebootcontrol/lang/de/module.json
+++ b/modules-available/rebootcontrol/lang/de/module.json
@@ -1,5 +1,4 @@
{
"module_name": "Reboot Control",
- "notAssigned": "Nicht zugewiesen",
"page_title": "Reboot Control"
} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/lang/de/permissions.json b/modules-available/rebootcontrol/lang/de/permissions.json
new file mode 100644
index 00000000..12ec4c83
--- /dev/null
+++ b/modules-available/rebootcontrol/lang/de/permissions.json
@@ -0,0 +1,5 @@
+{
+ "action.shutdown": "Client herunterfahren.",
+ "action.reboot": "Client neustarten.",
+ "newkeypair": "Neues Schlüsselpaar generieren."
+} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/lang/de/template-tags.json b/modules-available/rebootcontrol/lang/de/template-tags.json
index c5bd1670..c678ef88 100644
--- a/modules-available/rebootcontrol/lang/de/template-tags.json
+++ b/modules-available/rebootcontrol/lang/de/template-tags.json
@@ -1,12 +1,18 @@
{
+ "lang_activeTasks": "Laufende Jobs",
"lang_authFail": "Authentifizierung fehlgeschlagen",
"lang_client": "Client",
+ "lang_clientCount": "# Clients",
+ "lang_confirmNewKeypair": "Wirklich neues Schl\u00fcsselpaar erzeugen?",
"lang_connecting": "Verbinde...",
"lang_error": "Nicht erreichbar",
"lang_genNew": "Neues Schl\u00fcsselpaar generieren",
"lang_ip": "IP",
+ "lang_kexecRebootCheck": "Schneller Reboot direkt in bwLehrpool",
"lang_location": "Standort",
"lang_minutes": " Minuten",
+ "lang_mode": "Modus",
+ "lang_newKeypairExplanation": "Sie k\u00f6nnen ein neues Schl\u00fcsselpaar erzeugen lassen. In diesem Fall wird das alte Schl\u00fcsselpaar verworfen, sodass alle zum jetzigen Zeitpunkt bereits gestarteten Rechner nicht mehr aus der Ferne bedient werden k\u00f6nnen, bis diese manuell neugestartet wurden.",
"lang_off": "Aus",
"lang_on": "An",
"lang_online": "Online",
@@ -16,6 +22,7 @@
"lang_rebootButton": "Neustarten",
"lang_rebootCheck": "Wollen Sie die ausgew\u00e4hlten Rechner wirklich neustarten?",
"lang_rebootControl": "Reboot Control",
+ "lang_rebootIn": "Neustart in:",
"lang_rebooting": "Neustart...",
"lang_selectall": "Alle ausw\u00e4hlen",
"lang_selected": "Ausgew\u00e4hlt",
@@ -27,6 +34,6 @@
"lang_shutdownCheck": "Wollen Sie die ausgew\u00e4hlten Rechner wirklich herunterfahren?",
"lang_shutdownIn": "Herunterfahren in: ",
"lang_status": "Status",
- "lang_unselectall": "Alle abw\u00e4hlen",
- "lang_user": "Nutzer"
+ "lang_time": "Zeit",
+ "lang_unselectall": "Alle abw\u00e4hlen"
} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/lang/en/module.json b/modules-available/rebootcontrol/lang/en/module.json
index 129140dd..1f325354 100644
--- a/modules-available/rebootcontrol/lang/en/module.json
+++ b/modules-available/rebootcontrol/lang/en/module.json
@@ -1,5 +1,4 @@
{
"module_name": "Reboot Control",
- "notAssigned": "Not assigned",
"page_title": "Reboot Control"
} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/lang/en/permissions.json b/modules-available/rebootcontrol/lang/en/permissions.json
new file mode 100644
index 00000000..34badbaf
--- /dev/null
+++ b/modules-available/rebootcontrol/lang/en/permissions.json
@@ -0,0 +1,5 @@
+{
+ "action.shutdown": "Shutdown Client.",
+ "action.reboot": "Reboot Client.",
+ "newkeypair": "Generate new Keypair."
+} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/lang/en/template-tags.json b/modules-available/rebootcontrol/lang/en/template-tags.json
index 63a5b4a8..c64014ff 100644
--- a/modules-available/rebootcontrol/lang/en/template-tags.json
+++ b/modules-available/rebootcontrol/lang/en/template-tags.json
@@ -1,12 +1,18 @@
{
+ "lang_activeTasks": "Active tasks",
"lang_authFail": "Authentication failed",
"lang_client": "Client",
+ "lang_clientCount": "# clients",
+ "lang_confirmNewKeypair": "Really create new key pair?",
"lang_connecting": "Connecting...",
"lang_error": "Not available",
"lang_genNew": "Generate new keypair",
"lang_ip": "IP",
+ "lang_kexecRebootCheck": "Quick reboot straight to bwLehrpool (kexec)",
"lang_location": "Location",
"lang_minutes": " Minutes",
+ "lang_mode": "Mode",
+ "lang_newKeypairExplanation": "You can create a new keypair, which will replace the old one. Please note that after doing so, you cannot poweroff or reboot clients that are already running, since they still use the old key. They have to be rebooted manually first.",
"lang_off": "Off",
"lang_on": "On",
"lang_online": "Online",
@@ -16,6 +22,7 @@
"lang_rebootButton": "Reboot",
"lang_rebootCheck": "Do you really want to reboot the selected clients?",
"lang_rebootControl": "Reboot Control",
+ "lang_rebootIn": "Reboot in:",
"lang_rebooting": "Rebooting...",
"lang_selectall": "Select all",
"lang_selected": "Selected",
@@ -27,6 +34,6 @@
"lang_shutdownCheck": "Do you really want to shut down the selected clients?",
"lang_shutdownIn": "Shutdown in: ",
"lang_status": "Status",
- "lang_unselectall": "Unselect all",
- "lang_user": "User"
+ "lang_time": "Time",
+ "lang_unselectall": "Unselect all"
} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/page.inc.php b/modules-available/rebootcontrol/page.inc.php
index fc3ded8f..3a438504 100644
--- a/modules-available/rebootcontrol/page.inc.php
+++ b/modules-available/rebootcontrol/page.inc.php
@@ -20,33 +20,57 @@ class Page_RebootControl extends Page
$this->action = Request::any('action', 'show', 'string');
- if ($this->action === 'startReboot' || $this->action === 'startShutdown') {
- $clients = Request::post('clients');
- if (!is_array($clients) || empty($clients)) {
+ if ($this->action === 'reboot' || $this->action === 'shutdown') {
+
+ $requestedClients = Request::post('clients', false, 'array');
+ if (!is_array($requestedClients) || empty($requestedClients)) {
Message::addError('no-clients-selected');
Util::redirect();
}
- $locationId = Request::post('locationId', false, 'int');
- if ($locationId === false) {
- Message::addError('locations.invalid-location-id', $locationId);
- Util::redirect();
- }
- $shutdown = $this->action === "startShutdown";
- $minutes = Request::post('minutes', 0, 'int');
- $list = RebootQueries::getMachinesByUuid($clients);
- if (count($list) !== count($clients)) {
+ $actualClients = RebootQueries::getMachinesByUuid($requestedClients);
+ if (count($actualClients) !== count($requestedClients)) {
// We could go ahead an see which ones were not found in DB but this should not happen anyways unless the
// user manipulated the request
Message::addWarning('some-machine-not-found');
}
- // TODO: Iterate over list and check if a locationid is not in permissions
- // TODO: we could also check if the locationid is equal or a sublocation of the $locationId from above
- // (this would be more of a sanity check though, or does the UI allow selecting machines from different locations)
-
- $task = RebootControl::execute($list, $shutdown, $minutes, $locationId);
-
- Util::redirect("?do=rebootcontrol&taskid=".$task["id"]);
+ // Filter ones with no permission
+ foreach (array_keys($actualClients) as $idx) {
+ if (!User::hasPermission('action.' . $this->action, $actualClients[$idx]['locationid'])) {
+ Message::addWarning('locations.no-permission-location', $actualClients[$idx]['locationid']);
+ unset($actualClients[$idx]);
+ } else {
+ $locationId = $actualClients[$idx]['locationid'];
+ }
+ }
+ // See if anything is left
+ if (!is_array($actualClients) || empty($actualClients)) {
+ Message::addError('no-clients-selected');
+ Util::redirect();
+ }
+ usort($actualClients, function($a, $b) {
+ $a = ($a['state'] === 'IDLE' || $a['state'] === 'OCCUPIED');
+ $b = ($b['state'] === 'IDLE' || $b['state'] === 'OCCUPIED');
+ if ($a === $b)
+ return 0;
+ return $a ? -1 : 1;
+ });
+ if ($this->action === 'shutdown') {
+ $mode = 'SHUTDOWN';
+ $minutes = Request::post('s-minutes', 0, 'int');
+ } elseif (Request::any('quick', false, 'string') === 'on') {
+ $mode = 'KEXEC_REBOOT';
+ $minutes = Request::post('r-minutes', 0, 'int');
+ } else {
+ $mode = 'REBOOT';
+ $minutes = Request::post('r-minutes', 0, 'int');
+ }
+ $task = RebootControl::execute($actualClients, $mode, $minutes, $locationId);
+ if (Taskmanager::isTask($task)) {
+ Util::redirect("?do=rebootcontrol&taskid=" . $task["id"]);
+ } else {
+ Util::redirect("?do=rebootcontrol");
+ }
}
}
@@ -59,25 +83,76 @@ class Page_RebootControl extends Page
{
if ($this->action === 'show') {
- $taskId = Request::get("taskid");
+ $data = [];
+ $task = Request::get("taskid", false, 'string');
+ if ($task !== false) {
+ $task = Taskmanager::status($task);
+ }
- if ($taskId && Taskmanager::isTask($taskId)) {
- $task = Taskmanager::status($taskId);
- $data['taskId'] = $taskId;
+ if (Taskmanager::isTask($task)) {
+
+ $data['taskId'] = $task['id'];
$data['locationId'] = $task['data']['locationId'];
$data['locationName'] = Location::getName($task['data']['locationId']);
- $data['clients'] = $task['data']['clients'];
+ $uuids = array_map(function($entry) {
+ return $entry['machineuuid'];
+ }, $task['data']['clients']);
+ $data['clients'] = RebootQueries::getMachinesByUuid($uuids);
Render::addTemplate('status', $data);
+
} else {
+
//location you want to see, default are "not assigned" clients
- $requestedLocation = Request::get('location', 0, 'int');
+ $requestedLocation = Request::get('location', false, 'int');
+ $allowedLocs = User::getAllowedLocations("action.*");
+ if (empty($allowedLocs)) {
+ User::assertPermission('action.*');
+ }
+
+ if ($requestedLocation === false) {
+ if (in_array(0, $allowedLocs)) {
+ $requestedLocation = 0;
+ } else {
+ $requestedLocation = reset($allowedLocs);
+ }
+ }
- $data['data'] = RebootQueries::getMachineTable($requestedLocation);
$data['locations'] = Location::getLocations($requestedLocation, 0, true);
+ // disable each location user has no permission for
+ foreach ($data['locations'] as &$loc) {
+ if (!in_array($loc["locationid"], $allowedLocs)) {
+ $loc["disabled"] = "disabled";
+ } elseif ($loc["locationid"] == $requestedLocation) {
+ $data['location'] = $loc['locationname'];
+ }
+ }
+ // Always show public key (it's public, isn't it?)
$data['pubKey'] = SSHKey::getPublicKey();
- Render::addTemplate('_page', $data);
+ // Only enable shutdown/reboot-button if user has permission for the location
+ Permission::addGlobalTags($data['perms'], $requestedLocation, ['newkeypair', 'action.shutdown', 'action.reboot']);
+
+ Render::addTemplate('header', $data);
+
+ // only fill table if user has at least one permission for the location
+ if (!in_array($requestedLocation, $allowedLocs)) {
+ Message::addError('locations.no-permission-location', $requestedLocation);
+ } else {
+ $data['data'] = RebootQueries::getMachineTable($requestedLocation);
+ Render::addTemplate('_page', $data);
+ }
+
+ // Append list of active reboot/shutdown tasks
+ $active = RebootControl::getActiveTasks($allowedLocs);
+ if (!empty($active)) {
+ foreach ($active as &$entry) {
+ $entry['locationName'] = Location::getName($entry['locationId']);
+ }
+ unset($entry);
+ Render::addTemplate('task-list', ['list' => $active]);
+ }
+
}
}
}
@@ -86,6 +161,7 @@ class Page_RebootControl extends Page
{
$this->action = Request::post('action', false, 'string');
if ($this->action === 'generateNewKeypair') {
+ User::assertPermission("newkeypair");
Property::set("rebootcontrol-private-key", false);
echo SSHKey::getPublicKey();
} else {
diff --git a/modules-available/rebootcontrol/permissions/permissions.json b/modules-available/rebootcontrol/permissions/permissions.json
new file mode 100644
index 00000000..a058ffbf
--- /dev/null
+++ b/modules-available/rebootcontrol/permissions/permissions.json
@@ -0,0 +1,11 @@
+{
+ "newkeypair": {
+ "location-aware": false
+ },
+ "action.reboot": {
+ "location-aware": true
+ },
+ "action.shutdown": {
+ "location-aware": true
+ }
+} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/style.css b/modules-available/rebootcontrol/style.css
index 442cd5de..e35bce29 100644
--- a/modules-available/rebootcontrol/style.css
+++ b/modules-available/rebootcontrol/style.css
@@ -16,12 +16,8 @@
margin-bottom: 0;
}
-#rebootButton, #settingsButton, #selectAllButton, #unselectAllButton {
- margin-left: 10px;
-}
-
-#rebootButton, #shutdownButton, #selectAllButton, #unselectAllButton {
- width: 140px;
+.select-button {
+ min-width: 150px;
}
#dataTable {
@@ -32,11 +28,6 @@
#shutdownTimer {
text-align: center;
}
-#pubKeyTitle {
- display: inline-block;
- margin-top: 7px;
- margin-bottom: 20px;
-}
pre {
white-space: pre-wrap;
diff --git a/modules-available/rebootcontrol/templates/_page.html b/modules-available/rebootcontrol/templates/_page.html
index 1bef8dd4..a124e165 100644
--- a/modules-available/rebootcontrol/templates/_page.html
+++ b/modules-available/rebootcontrol/templates/_page.html
@@ -1,93 +1,53 @@
-<div class="page-header">
- <button type="button" id="settingsButton" class="btn btn-default pull-right" data-toggle="modal" data-target="#settingsModal"><span class="glyphicon glyphicon-cog"></span> {{lang_settings}}</button>
- <h1>{{lang_rebootControl}}</h1>
-</div>
+<h3>{{location}}</h3>
-
-<form id="tableDataForm" method="post" action="?do=rebootcontrol" class="form-inline">
+<form method="post" action="?do=rebootcontrol" class="form-inline">
<input type="hidden" name="token" value="{{token}}">
<div class="row">
<div class="col-md-12">
- <label>{{lang_location}}:
- <select id="locationDropdown" name="locationId" class="form-control" onchange="selectLocation()">
- {{#locations}}
- <option value="{{locationid}}" {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option>
- {{/locations}}
- </select>
- </label>
- <button type="button" id="selectAllButton" class="btn btn-primary pull-right" onclick="selectAllRows()"><span class="glyphicon glyphicon-check"></span> {{lang_selectall}}</button>
- <button type="button" id="unselectAllButton" class="btn btn-default pull-right" onclick="unselectAllRows()" style="display: none;"><span class="glyphicon glyphicon-unchecked"></span> {{lang_unselectall}}</button>
- <button type="button" id="rebootButton" class="btn btn-warning pull-right" data-toggle="modal" data-target="#rebootModal" disabled><span class="glyphicon glyphicon-repeat"></span> {{lang_rebootButton}}</button>
- <button type="button" id="shutdownButton" class="btn btn-danger pull-right" data-toggle="modal" data-target="#shutdownModal" disabled><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button>
- </div>
- </div>
- <div class="row">
- <div class="col-md-12">
<table class="table table-condensed table-hover stupidtable" id="dataTable">
<thead>
- <tr>
- <th data-sort="string">{{lang_client}}</th>
- <th data-sort="ipv4">{{lang_ip}}</th>
- <th data-sort="string">{{lang_status}}</th>
- <th data-sort="string">{{lang_session}}</th>
- <th data-sort="string">{{lang_user}}</th>
- <th data-sort="int" data-sort-default="desc">{{lang_selected}}</th>
- </tr>
+ <tr>
+ <th data-sort="string">{{lang_client}}</th>
+ <th data-sort="ipv4">{{lang_ip}}</th>
+ <th data-sort="string">{{lang_status}}</th>
+ <th data-sort="string">{{lang_session}}</th>
+ <th data-sort="string">{{lang_user}}</th>
+ <th data-sort="int" data-sort-default="desc">{{lang_selected}}</th>
+ </tr>
</thead>
<tbody>
{{#data}}
- <tr>
- <td>
- {{hostname}}
- {{^hostname}}{{clientip}}{{/hostname}}
- </td>
- <td>{{clientip}}</td>
- <td class="statusColumn">
- {{#status}}
- <span class="text-success">{{lang_on}}</span>
- {{/status}}
- {{^status}}
- <span class="text-danger">{{lang_off}}</span>
- {{/status}}
- </td>
- <td>{{#status}}{{currentsession}}{{/status}}</td>
- <td>{{#status}}{{currentuser}}{{/status}}</td>
- <td data-sort-value="0" class="checkboxColumn">
- <div class="checkbox">
- <input id="m-{{machineuuid}}" type="checkbox" name="clients[]" value='{{machineuuid}}'>
- <label for="m-{{machineuuid}}"></label>
- </div>
- </td>
- </tr>
+ <tr>
+ <td>
+ {{hostname}}
+ {{^hostname}}{{clientip}}{{/hostname}}
+ </td>
+ <td>{{clientip}}</td>
+ <td class="statusColumn">
+ {{#status}}
+ <span class="text-success">{{lang_on}}</span>
+ {{/status}}
+ {{^status}}
+ <span class="text-danger">{{lang_off}}</span>
+ {{/status}}
+ </td>
+ <td>{{#status}}{{currentsession}}{{/status}}</td>
+ <td>{{#status}}{{currentuser}}{{/status}}</td>
+ <td data-sort-value="0" class="checkboxColumn slx-smallcol">
+ <div class="checkbox">
+ <input id="m-{{machineuuid}}" type="checkbox" name="clients[]" value='{{machineuuid}}'>
+ <label for="m-{{machineuuid}}"></label>
+ </div>
+ </td>
+ </tr>
{{/data}}
</tbody>
</table>
</div>
</div>
-
<!-- Modals -->
-
- <div id="settingsModal" class="modal fade" role="dialog">
- <div class="modal-dialog">
-
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal">&times;</button>
- <h4 class="modal-title"><b>{{lang_settings}}</b></h4>
- </div>
- <div class="modal-body">
- <span id="pubKeyTitle">{{lang_pubKey}}</span>
- <button class="btn btn-s btn-warning pull-right" onclick="generateNewKeypair()" type="button"><span class="glyphicon glyphicon-refresh"></span> {{lang_genNew}}</button>
- <pre id="pubKey">{{pubKey}}</pre>
- </div>
- <div class="modal-footer">
- </div>
- </div>
- </div>
- </div>
-
<div class ="modal fade" id="rebootModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
@@ -96,17 +56,27 @@
<h4 class="modal-title" id="myModalLabel">{{lang_rebootButton}}</h4>
</div>
<div class="modal-body">
- {{lang_rebootCheck}}
+ <div>{{lang_rebootCheck}}</div>
+ <div>{{lang_rebootIn}} <input name="r-minutes" title="{{lang_shutdownIn}}" type="number" value="0" min="0" pattern="\d+"> {{lang_minutes}}</div>
+ <div>
+ <div class="checkbox checkbox-inline">
+ <input name="quick" type="checkbox" value="on" id="rb-quick">
+ <label for="rb-quick">{{lang_kexecRebootCheck}}</label>
+ </div>
+ </div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="submit" name="action" value="startReboot" class="btn btn-warning"><span class="glyphicon glyphicon-repeat"></span> {{lang_reboot}}</button>
+ <button type="submit" {{perms.action.reboot.disabled}} name="action" value="reboot" class="btn btn-warning">
+ <span class="glyphicon glyphicon-repeat"></span>
+ {{lang_reboot}}
+ </button>
</div>
</div>
</div>
</div>
- <div class ="modal fade" id="shutdownModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class ="modal fade" id="shutdownModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel2">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
@@ -114,12 +84,15 @@
<h4 class="modal-title" id="myModalLabel2">{{lang_shutdownButton}}</h4>
</div>
<div class="modal-body">
- {{lang_shutdownCheck}}
- {{lang_shutdownIn}} <input id="shutdownTimer" name="minutes" title="{{lang_shutdownIn}}" type="number" value="0" min="0" onkeypress="return isNumberKey(event)"> {{lang_minutes}}
+ <div>{{lang_shutdownCheck}}</div>
+ {{lang_shutdownIn}} <input name="s-minutes" title="{{lang_shutdownIn}}" type="number" value="0" min="0" pattern="\d+"> {{lang_minutes}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="submit" name="action" value="startShutdown" class="btn btn-danger"><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button>
+ <button type="submit" {{perms.action.shutdown.disabled}} name="action" value="shutdown" class="btn btn-danger">
+ <span class="glyphicon glyphicon-off"></span>
+ {{lang_shutdownButton}}
+ </button>
</div>
</div>
</div>
@@ -128,104 +101,76 @@
<script type="application/javascript">
+ var $dataTable;
+
document.addEventListener("DOMContentLoaded", function() {
- markCheckedRows();
- $('input:checkbox').change(
- function(){
+ $dataTable = $("#dataTable");
+ markCheckedRows();
+ // Handle change of checkboxes in table
+ $('input:checkbox').change(function() {
+ var $this = $(this);
//give each checkbox the function to mark the row (in green)
- if ($(this).is(':checked')) {
- markRows($(this).closest("tr"), true);
- $(this).closest("td").data("sort-value", 1);
+ if ($this.is(':checked')) {
+ markRows($this.closest("tr"), true);
+ $this.closest("td").data("sort-value", 1);
} else {
- markRows($(this).closest("tr"), false);
- $(this).closest("td").data("sort-value", 0);
+ markRows($this.closest("tr"), false);
+ $this.closest("td").data("sort-value", 0);
}
//if all are checked, change the selectAll-Button to unselectAll. if one is not checked, change unselectAll to selectAll
- var dataTable = $("#dataTable");
- var unchecked = dataTable.find("input[type=checkbox]:not(:checked)").length;
- if (unchecked == 0) {
+ var unchecked = $dataTable.find("input:checkbox:not(:checked)").length;
+ var checked = $dataTable.find("input:checkbox:checked").length;
+ if (unchecked === 0) {
$('#selectAllButton').hide();
$('#unselectAllButton').show();
- } else if (unchecked == 1) {
+ } else if (checked === 0) {
$('#selectAllButton').show();
$('#unselectAllButton').hide();
}
//if no client is selected, disable the shutdown/reboot button, and enable them if a client is selected
- var checked = dataTable.find("input[type=checkbox]:checked").length;
- if (checked == 0) {
- $('#rebootButton').prop('disabled', true);
- $('#shutdownButton').prop('disabled', true);
- } else {
- $('#rebootButton').prop('disabled', false);
- $('#shutdownButton').prop('disabled', false);
- }
- });
+ $('#rebootButton').prop('disabled', checked === 0 || '{{perms.action.reboot.disabled}}' === 'disabled');
+ $('#shutdownButton').prop('disabled', checked === 0 || '{{perms.action.shutdown.disabled}}' === 'disabled');
+ });
+ // Propagate click on column with checkbox to checkbox
$('.checkboxColumn').click(function(e) {
if (e.target === this) {
- $(this).find('input[type="checkbox"]').click();
+ $(this).find('input:checkbox').click();
}
});
+ // Arm the (de)select all buttons
+ $('#selectAllButton').click(function() { selectAllRows(true); });
+ $('#unselectAllButton').click(function() { selectAllRows(false); });
});
- // Change Location when selected in Dropdown Menu
- function selectLocation() {
- var dropdown = $("#locationDropdown");
- var location = dropdown.val();
- window.location.replace("?do=rebootcontrol&location="+location);
- }
-
// Check all checkboxes, change selectAll button, make shutdown/reboot button enabled as clients will certainly be selected
- function selectAllRows() {
- var checked = $("tr input:checkbox:checked");
-
- //change button
- $('#selectAllButton').hide();
- $('#unselectAllButton').show();
-
- //check rows and mark them
- $('input[type="checkbox"]', '#dataTable').prop('checked', true);
- markRows($("tr:not(:first)"), true);
- $(".checkboxColumn").data("sort-value", 1);
-
- //enable shutdown/reboot button
- $('#rebootButton').prop('disabled', false);
- $('#shutdownButton').prop('disabled', false);
- }
-
- // Uncheck all checkboxes, change unselectAll Button, make shutdown/reboot button disabled as clients will certainly be not selected
- function unselectAllRows() {
- //change button
- $('#selectAllButton').show();
- $('#unselectAllButton').hide();
-
- //uncheck rows and unmark them
- $('input[type="checkbox"]', '#dataTable').prop('checked', false);
- markRows($("tr"), false);
- $(".checkboxColumn").data("sort-value", 0);
-
- //disable shutdown/reboot button
- $('#rebootButton').prop('disabled', true);
- $('#shutdownButton').prop('disabled', true);
+ function selectAllRows(selected) {
+ var $box = $dataTable.find('input:checkbox');
+ if ($box.length === 0) return;
+ if (selected) {
+ $box = $box.filter(':not(:checked)');
+ } else {
+ $box = $box.filter(':checked');
+ }
+ if ($box.length === 0) return;
+ $box.prop('checked', !!selected).trigger('change');
}
- // mark all previous checked rows (used when loading site)
+ // mark all previous checked rows (used when loading site), enable (de)select all if list is not empty
function markCheckedRows() {
- var checked = $("tr input:checkbox:checked");
- markRows(checked.closest("tr"), true);
- var unchecked = $("#dataTable").find("input[type=checkbox]:not(:checked)").length;
- if(unchecked == 0) {
+ var $checked = $dataTable.find("input:checkbox:checked");
+ markRows($checked.closest("tr"), true);
+ var $unchecked = $dataTable.find("input:checkbox:not(:checked)");
+ markRows($unchecked.closest("tr"), false);
+ if($unchecked.length === 0) {
$('#selectAllButton').hide();
$('#unselectAllButton').show();
}
- }
-
- // only allow numbers to get typed into the "shutdown in X Minutes" box.
- function isNumberKey(evt){
- var charCode = (evt.which) ? evt.which : event.keyCode;
- return !(charCode > 31 && (charCode < 48 || charCode > 57));
+ if ($unchecked.length > 0 || $checked.length > 0) {
+ $('.select-button').prop('disabled', false);
+ }
}
function markRows($rows, marked) {
@@ -236,15 +181,4 @@
}
}
- function generateNewKeypair() {
- $.ajax({
- url: '?do=rebootcontrol',
- type: 'POST',
- data: { action: "generateNewKeypair", token: TOKEN },
- success: function(value) {
- $('#pubKey').text(value);
- }
- });
- }
-
</script> \ No newline at end of file
diff --git a/modules-available/rebootcontrol/templates/header.html b/modules-available/rebootcontrol/templates/header.html
new file mode 100644
index 00000000..e171ccd6
--- /dev/null
+++ b/modules-available/rebootcontrol/templates/header.html
@@ -0,0 +1,79 @@
+<div class="page-header">
+ <button type="button" id="settingsButton" class="btn btn-default pull-right" data-toggle="modal" data-target="#settingsModal"><span class="glyphicon glyphicon-cog"></span> {{lang_settings}}</button>
+ <h1>{{lang_rebootControl}}</h1>
+</div>
+
+<div>
+ <label>{{lang_location}}:
+ <select id="locationDropdown" class="form-control" onchange="selectLocation()">
+ {{#locations}}
+ <option value="{{locationid}}" {{disabled}} {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option>
+ {{/locations}}
+ </select>
+ </label>
+ <div class="pull-right">
+ <button type="button" id="shutdownButton" class="btn btn-danger action-button" data-toggle="modal" data-target="#shutdownModal" disabled>
+ <span class="glyphicon glyphicon-off"></span>
+ {{lang_shutdownButton}}
+ </button>
+ <button type="button" id="rebootButton" class="btn btn-warning action-button" data-toggle="modal" data-target="#rebootModal" disabled>
+ <span class="glyphicon glyphicon-repeat"></span>
+ {{lang_rebootButton}}
+ </button>
+ <button type="button" id="selectAllButton" class="btn btn-primary select-button" disabled>
+ <span class="glyphicon glyphicon-check"></span>
+ {{lang_selectall}}
+ </button>
+ <button type="button" id="unselectAllButton" class="btn btn-default select-button collapse" disabled>
+ <span class="glyphicon glyphicon-unchecked"></span>
+ {{lang_unselectall}}
+ </button>
+ </div>
+</div>
+
+<div id="settingsModal" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">&times;</button>
+ <h4 class="modal-title"><b>{{lang_settings}}</b></h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_pubKey}}</p>
+ <pre id="pubkey">{{pubKey}}</pre>
+ <p>{{lang_newKeypairExplanation}}</p>
+ </div>
+ <div class="modal-footer">
+ <button {{perms.newkeypair.disabled}} class="btn btn-danger pull-right" onclick="generateNewKeypair()" type="button">
+ <span class="glyphicon glyphicon-refresh"></span>
+ {{lang_genNew}}
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
+
+<script type="application/javascript">
+
+ // Change Location when selected in Dropdown Menu
+ function selectLocation() {
+ var dropdown = $("#locationDropdown");
+ var location = dropdown.val();
+ window.location.replace("?do=rebootcontrol&location="+location);
+ }
+
+ function generateNewKeypair() {
+ if (!confirm('{{lang_confirmNewKeypair}}'))
+ return;
+ $.ajax({
+ url: '?do=rebootcontrol',
+ type: 'POST',
+ data: { action: "generateNewKeypair", token: TOKEN },
+ success: function(value) {
+ $('#pubkey').text(value);
+ }
+ });
+ }
+
+</script> \ No newline at end of file
diff --git a/modules-available/rebootcontrol/templates/status.html b/modules-available/rebootcontrol/templates/status.html
index c2fdab46..c05b2fad 100644
--- a/modules-available/rebootcontrol/templates/status.html
+++ b/modules-available/rebootcontrol/templates/status.html
@@ -7,8 +7,6 @@
</form>
</div>
-<div data-tm-id="{{taskId}}" data-tm-log="error" data-tm-callback="updateStatus"></div>
-
<div>
<table class="table table-hover stupidtable" id="dataTable">
<thead>
@@ -24,7 +22,7 @@
<tbody>
{{#clients}}
<tr>
- <td>{{machineuuid}}</td>
+ <td>{{hostname}}{{^hostname}}{{machineuuid}}{{/hostname}}</td>
<td>{{clientip}}</td>
<td id="status-{{machineuuid}}"></td>
</tr>
@@ -33,6 +31,8 @@
</table>
</div>
+<div data-tm-id="{{taskId}}" data-tm-log="error" data-tm-callback="updateStatus"></div>
+
<script type="application/javascript">
statusStrings = {
"CONNECTING" : "{{lang_connecting}}",
@@ -50,12 +50,20 @@
return;
var clientStatus = task.data.clientStatus;
for (var uuid in clientStatus) {
- if (clientStatus.hasOwnProperty(uuid)) {
- var shutdownTime = ' ';
- if (clientStatus[uuid] === 'SHUTDOWN_AT' || clientStatus[uuid] === 'REBOOT_AT') {
- shutdownTime += task.data.time;
- }
- $("#status-" + uuid).text(statusStrings[clientStatus[uuid]] + shutdownTime);
+ if (!clientStatus.hasOwnProperty(uuid))
+ continue;
+ var $s = $("#status-" + uuid);
+ var status = clientStatus[uuid];
+ if ($s.data('state') === status)
+ continue;
+ $s.data('state', status);
+ var text = statusStrings[status];
+ if (status === 'SHUTDOWN_AT' || status === 'REBOOT_AT') {
+ text += ' ' + task.data.time;
+ }
+ $s.text(text);
+ if (status === 'CONNECTING' || status === 'REBOOTING') {
+ $s.append('<span class="glyphicon glyphicon-hourglass"></span>');
}
}
}
diff --git a/modules-available/rebootcontrol/templates/task-list.html b/modules-available/rebootcontrol/templates/task-list.html
new file mode 100644
index 00000000..063ba949
--- /dev/null
+++ b/modules-available/rebootcontrol/templates/task-list.html
@@ -0,0 +1,33 @@
+<h3>{{lang_activeTasks}}</h3>
+<table class="table">
+ <thead>
+ <tr>
+ <th>{{lang_mode}}</th>
+ <th>{{lang_location}}</th>
+ <th>{{lang_time}}</th>
+ <th>{{lang_clientCount}}</th>
+ <th>{{lang_status}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#list}}
+ <tr>
+ <td>
+ <a href="?do=rebootcontrol&amp;taskid={{taskId}}">{{mode}}</a>
+ </td>
+ <td>
+ {{locationName}}
+ </td>
+ <td>
+ {{time}}
+ </td>
+ <td>
+ {{clientCount}}
+ </td>
+ <td>
+ {{status}}
+ </td>
+ </tr>
+ {{/list}}
+ </tbody>
+</table> \ No newline at end of file
diff --git a/modules-available/roomplanner/baseconfig/getconfig.inc.php b/modules-available/roomplanner/baseconfig/getconfig.inc.php
index f4708547..79af974b 100644
--- a/modules-available/roomplanner/baseconfig/getconfig.inc.php
+++ b/modules-available/roomplanner/baseconfig/getconfig.inc.php
@@ -1,3 +1,24 @@
<?php
ConfigHolder::add("SLX_PVS_CONFIG_URL", 'http://' . $_SERVER['SERVER_ADDR'] . $_SERVER['SCRIPT_NAME'] . '?do=roomplanner');
+
+/**
+ * Make sure we switch to dedicated mode if this is a hybrid mode
+ * manager and we're in exam mode.
+ * Also disable exam mode for any kind of manager.
+ */
+ConfigHolder::addPostHook(function() {
+ $exam = (bool)ConfigHolder::get('SLX_EXAM');
+ $hybrid = ConfigHolder::get('SLX_PVS_HYBRID') === 'yes';
+ $dedi = (bool)ConfigHolder::get('SLX_PVS_DEDICATED');
+ if ($exam) {
+ if ($dedi || $hybrid) {
+ ConfigHolder::add('SLX_EXAM', false, 100000);
+ ConfigHolder::add('SLX_SYSTEMD_TARGET', false, 100000);
+ }
+ if ($hybrid) {
+ ConfigHolder::add('SLX_PVS_HYBRID', false, 100000);
+ ConfigHolder::add('SLX_PVS_DEDICATED', 'yes', 100000);
+ }
+ }
+}); \ No newline at end of file
diff --git a/modules-available/roomplanner/clientscript.js b/modules-available/roomplanner/clientscript.js
index bd29c06c..823c212a 100644
--- a/modules-available/roomplanner/clientscript.js
+++ b/modules-available/roomplanner/clientscript.js
@@ -184,6 +184,7 @@ function onPcDelete(muuid) {
value = subnetMachines[i];
}
});
+ if (!value) return;
}
value.fixedlocationid = null;
makeCombinedFieldSingle(value);
diff --git a/modules-available/roomplanner/config.json b/modules-available/roomplanner/config.json
index 537714c3..62f38773 100644
--- a/modules-available/roomplanner/config.json
+++ b/modules-available/roomplanner/config.json
@@ -1,3 +1,10 @@
{
- "dependencies": ["js_jqueryui", "js_selectize", "bootstrap_dialog", "statistics", "locations", "runmode"]
-}
+ "dependencies": [
+ "js_jqueryui",
+ "js_selectize",
+ "bootstrap_dialog",
+ "statistics",
+ "locations",
+ "runmode"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/roomplanner/hooks/runmode/config.json b/modules-available/roomplanner/hooks/runmode/config.json
index 27c601fd..3cbf4a6c 100644
--- a/modules-available/roomplanner/hooks/runmode/config.json
+++ b/modules-available/roomplanner/hooks/runmode/config.json
@@ -3,5 +3,6 @@
"isClient": false,
"configHook": "PvsGenerator::runmodeConfigHook",
"allowGenericEditor": false,
- "deleteUrlSnippet": "locationid="
+ "deleteUrlSnippet": "locationid=",
+ "permission": ".roomplanner.edit"
} \ No newline at end of file
diff --git a/modules-available/roomplanner/inc/pvsgenerator.inc.php b/modules-available/roomplanner/inc/pvsgenerator.inc.php
index cda32fce..5a7de9f0 100644
--- a/modules-available/roomplanner/inc/pvsgenerator.inc.php
+++ b/modules-available/roomplanner/inc/pvsgenerator.inc.php
@@ -222,7 +222,6 @@ class PvsGenerator
if (isset($data['dedicatedmgr']) && $data['dedicatedmgr']) {
ConfigHolder::add("SLX_ADDONS", false, 100000);
ConfigHolder::add("SLX_PVS_DEDICATED", 'yes');
- ConfigHolder::add("SLX_EXAM", false, 100000);
ConfigHolder::add("SLX_AUTOLOGIN", 'ON', 100000);
} else {
ConfigHolder::add("SLX_PVS_HYBRID", 'yes');
diff --git a/modules-available/roomplanner/js/grid.js b/modules-available/roomplanner/js/grid.js
index 466e42aa..697d7c3f 100644
--- a/modules-available/roomplanner/js/grid.js
+++ b/modules-available/roomplanner/js/grid.js
@@ -1,5 +1,9 @@
+var $gridInner = $('#draw-element-area');
+var $gridFrame = $('#drawpanel');
+var $grid = $('#drawarea');
+
if (!roomplanner) var roomplanner = {
-
+
getScaleFactor: function() {
return this.settings.scale/100;
},
@@ -36,9 +40,10 @@ if (!roomplanner) var roomplanner = {
if (!(new RegExp(".*(east|south|west|north)$").test($(el).attr('itemlook')))) {
return;
}
-
- $(el).append('<div class="rotationHandle glyphicon glyphicon-repeat"></div>');
- $(el).find('.rotationHandle').click(function () {
+
+ var $e = $('<div class="pcHandle glyphicon glyphicon-repeat"></div>');
+ $(el).append($e);
+ $e.click(function () {
var str = $(el).attr('itemlook');
if (str.indexOf('-') > -1){
var values =str.split('-');
@@ -89,16 +94,34 @@ if (!roomplanner) var roomplanner = {
}
});
},
- initTutor: function(el) {
+ initPcButtons: function(el) {
if ($(el).attr('itemtype') !== 'pc') return;
- $(el).append('<div class="tutorHandle glyphicon glyphicon-blackboard"></div>');
- $(el).find('.tutorHandle').click(function() {
- var wasTutor = ($(this).parent().attr('istutor') === 'true');
- $('[itemtype="pc"]').removeAttr('istutor');
- if (!wasTutor) {
- $(this).parent().attr('istutor', 'true');
- }
- });
+ var $e;
+ if (!PLANNER_READ_ONLY) {
+ $e = $('<div class="pcHandle glyphicon glyphicon-blackboard"></div>');
+ $(el).append($e);
+ $e.click(function () {
+ var wasTutor = ($(this).parent().attr('istutor') === 'true');
+ $('[itemtype="pc"]').removeAttr('istutor');
+ if (!wasTutor) {
+ $(this).parent().attr('istutor', 'true');
+ }
+ });
+ }
+ if (CAN_OPEN_STATS) {
+ $e = $('<div class="pcHandle glyphicon glyphicon-eye-open"></div>');
+ $(el).append($e);
+ $e.click(function () {
+ var uuid = $(this).parent().attr('muuid');
+ console.log('Click: ', uuid);
+ var url = '?do=statistics&uuid=' + uuid;
+ if (roomplanner.serialize() !== plannerLoadState) {
+ window.open(url);
+ } else {
+ window.location.href = url;
+ }
+ });
+ }
},
initTooltip: function(el) {
if ($(el).attr('itemtype') === 'pc') {
@@ -280,7 +303,7 @@ if (!roomplanner) var roomplanner = {
"computers": []
};
- var furniture = $('#draw-element-area div[itemtype="furniture"]');
+ var furniture = $gridInner.find('div[itemtype="furniture"]');
furniture.each(function(idx,el) {
objects.furniture.push({
"gridRow" : $(el).attr('gridRow'),
@@ -291,7 +314,7 @@ if (!roomplanner) var roomplanner = {
});
});
- var computers = $('#draw-element-area div[itemtype="pc"]');
+ var computers = $gridInner.find('div[itemtype="pc"]');
computers.each(function(idx,el) {
var object = {
@@ -326,7 +349,7 @@ if (!roomplanner) var roomplanner = {
var objects = object;
}
- $('#draw-element-area').html('');
+ $gridInner.html('');
function itemToHtml(item, itemtype, obstacle) {
var html = '<div itemtype="'+itemtype+'" style="position:absolute;" ';
@@ -334,16 +357,19 @@ if (!roomplanner) var roomplanner = {
if (!item.hasOwnProperty(prop)) continue;
html += prop+'="'+item[prop]+'" ';
}
- html += 'class="draggable ui-draggable';
- html+= '"></div>';
- return html;
+ html += 'class="ui-draggable';
+ if (!PLANNER_READ_ONLY) {
+ html += ' draggable';
+ }
+ html += '"></div>';
+ return html;
}
if (objects.furniture) {
var furniture = objects.furniture;
for (var piece in furniture) {
var item = itemToHtml(furniture[piece], "furniture", true);
- $('#draw-element-area').append(item);
+ $gridInner.append(item);
}
}
@@ -353,51 +379,53 @@ if (!roomplanner) var roomplanner = {
var computers = objects.computers;
for (var piece in computers) {
var item = itemToHtml(computers[piece], "pc", false);
- $('#draw-element-area').append(item);
+ $gridInner.append(item);
}
}
- $('#draw-element-area .draggable').each(function(idx,el) {
+ $gridInner.find('.draggable').each(function(idx,el) {
roomplanner.initDraggable(el);
roomplanner.initResizable(el);
roomplanner.initTooltip(el);
roomplanner.initRotation(el);
roomplanner.initDelete(el);
- roomplanner.initTutor(el);
+ });
+ $gridInner.find('.ui-draggable').each(function(idx,el) {
+ roomplanner.initPcButtons(el);
});
roomplanner.grid.scale(roomplanner.settings.scale);
roomplanner.fitContent();
},
clear: function() {
- $('#draw-element-area').html('');
+ $gridInner.html('');
}
};
roomplanner.grid = (function() {
var grid = {
resize: function() {
- var w = Math.max($('#drawpanel .panel-body').width(),roomplanner.settings.room.width*roomplanner.settings.scale)
- var h = Math.max($('#drawpanel .panel-body').height(),roomplanner.settings.room.height*roomplanner.settings.scale)
- $('#drawarea').width(w);
- $('#drawarea').height(h);
+ var w = Math.max($gridFrame.find('.panel-body').width(),roomplanner.settings.room.width*roomplanner.settings.scale)
+ var h = Math.max($gridFrame.find('.panel-body').height(),roomplanner.settings.room.height*roomplanner.settings.scale)
+ $grid.width(w);
+ $grid.height(h);
},
scale: function(num) {
- var area_left = parseInt($('#drawarea').css('left')) - $('#drawpanel .panel-body').width()/2 ;
- var area_top = parseInt($('#drawarea').css('top')) - $('#drawpanel .panel-body').height()/2;
+ var area_left = parseInt($grid.css('left')) - $gridFrame.find('.panel-body').width()/2 ;
+ var area_top = parseInt($grid.css('top')) - $gridFrame.find('.panel-body').height()/2;
var opts = {
- left: ((parseInt(area_left) * num / roomplanner.settings.scale ) + $('#drawpanel .panel-body').width()/2)+ "px" ,
- top: ((parseInt(area_top) * num / roomplanner.settings.scale ) + $('#drawpanel .panel-body').height()/2)+ "px"
+ left: ((parseInt(area_left) * num / roomplanner.settings.scale ) + $gridFrame.find('.panel-body').width()/2)+ "px" ,
+ top: ((parseInt(area_top) * num / roomplanner.settings.scale ) + $gridFrame.find('.panel-body').height()/2)+ "px"
};
- $('#drawarea').css(opts);
+ $grid.css(opts);
- $('#drawarea').css('background-size',num);
+ $grid.css('background-size',num);
roomplanner.settings.scale = num;
- $('#draw-element-area .ui-draggable').each(function(idx,item) {
+ $gridInner.find('.ui-draggable').each(function(idx,item) {
var $item = $(item);
var h = $item.attr('data-height') * roomplanner.getScaleFactor();
var w = $item.attr('data-width') * roomplanner.getScaleFactor();
@@ -406,10 +434,11 @@ roomplanner.grid = (function() {
var pos = roomplanner.getCellPositionFromGrid($item.attr('gridRow'),$item.attr('gridCol'));
$item.css({width: w+"px", height: h+"px", left: pos[0]+"px", top: pos[1]+"px"});
- $item.draggable("option","grid",[(roomplanner.settings.scale / 4), (roomplanner.settings.scale / 4)]);
-
- if (roomplanner.isElementResizable(item)) {
- $item.resizable("option","grid",[(roomplanner.settings.scale / 4), (roomplanner.settings.scale / 4)]);
+ if ($item.hasClass('draggable')) {
+ $item.draggable("option", "grid", [(roomplanner.settings.scale / 4), (roomplanner.settings.scale / 4)]);
+ if (roomplanner.isElementResizable(item)) {
+ $item.resizable("option", "grid", [(roomplanner.settings.scale / 4), (roomplanner.settings.scale / 4)]);
+ }
}
});
this.resize();
@@ -431,7 +460,7 @@ roomplanner.fitContent = function() {
var minY = 99999;
var maxX = -99999;
var maxY = -99999;
- $('#draw-element-area .ui-draggable').each(function(idx,item) {
+ $gridInner.find('.ui-draggable').each(function(idx,item) {
var $item = $(item);
var l = parseInt($item.attr('gridcol')) * roomplanner.settings.cellsize;
@@ -446,8 +475,8 @@ roomplanner.fitContent = function() {
});
if (minX > maxX)
return;
- var width = (maxX - minX) / $('#drawpanel .panel-body').width();
- var height = (maxY - minY) / $('#drawpanel .panel-body').height();
+ var width = (maxX - minX) / $gridFrame.find('.panel-body').width();
+ var height = (maxY - minY) / $gridFrame.find('.panel-body').height();
var scale;
if (width > height) {
scale = Math.floor(100 / width);
@@ -461,7 +490,7 @@ roomplanner.fitContent = function() {
top: -(minY * (scale / 100)) + "px"
};
- $('#drawarea').css(opts);
+ $grid.css(opts);
};
$(document).ready(function(){
@@ -480,12 +509,12 @@ $(document).ready(function(){
change: update,
slide: update,
stop: function(e, ui) {
- $('#drawarea').trigger('checkposition');
+ $grid.trigger('checkposition');
}
});
- $('#drawarea').bind('checkposition', function() {
+ $grid.bind('checkposition', function() {
if ($(this).offset().left > 0) {
$(this).css('left',0);
}
@@ -502,7 +531,7 @@ $(document).ready(function(){
}
});
- $('#drawarea').draggable({
+ $grid.draggable({
stop: function() {
$(this).trigger('checkposition');
}
@@ -512,7 +541,7 @@ $(document).ready(function(){
* adds droppable functionality to the draw area for the elements.
* drop event is only fired for elements added to the board from the toolbar.
*/
- $('#draw-element-area').droppable({
+ $gridInner.droppable({
accept: ".draggable",
drop: function(event, ui) {
@@ -528,8 +557,8 @@ $(document).ready(function(){
if (ui.helper != ui.draggable) {
- var leftPos = parseInt($(el).css('left'))-parseInt($('#drawarea').css('left'))-$('#drawpanel').offset().left;
- var topPos = parseInt($(el).css('top'))-parseInt($('#drawarea').css('top'))-($('#drawpanel').offset().top + $('#drawpanel .panel-heading').height());
+ var leftPos = parseInt($(el).css('left'))-parseInt($grid.css('left'))-$gridFrame.offset().left;
+ var topPos = parseInt($(el).css('top'))-parseInt($grid.css('top'))-($gridFrame.offset().top + $gridFrame.find('.panel-heading').height());
var cp = roomplanner.getCellPositionFromPixels(leftPos,topPos);
leftPos = cp[0];
topPos = cp[1];
@@ -575,8 +604,8 @@ $(document).ready(function(){
$(el).css('opacity',1);
if (ui.helper != ui.draggable) {
- var l = parseInt($(el).css('left'))-parseInt($('#drawarea').css('left'))-$('#drawpanel').offset().left;
- var t = parseInt($(el).css('top'))-parseInt($('#drawarea').css('top'))-($('#drawpanel').offset().top + $('#drawpanel .panel-heading').height());
+ var l = parseInt($(el).css('left'))-parseInt($grid.css('left'))-$gridFrame.offset().left;
+ var t = parseInt($(el).css('top'))-parseInt($grid.css('top'))-($gridFrame.offset().top + $gridFrame.find('.panel-heading').height());
var cp = roomplanner.getCellPositionFromPixels(l,t);
$(el).css('left',cp[0]);
$(el).css('top',cp[1]);
@@ -596,7 +625,7 @@ $(document).ready(function(){
if ($(el).attr('itemtype') == "pc") {
var uuids = [];
- var computers = $('#draw-element-area div[itemtype="pc"]');
+ var computers = $gridInner.find('div[itemtype="pc"]');
computers.each(function(idx,el) {
if ($(el).attr('muuid')) {
uuids.push($(el).attr('muuid'));
@@ -613,10 +642,10 @@ $(document).ready(function(){
roomplanner.initTooltip(el);
}
});
- }
- roomplanner.initDelete(el);
+ }
roomplanner.initRotation(el);
- roomplanner.initTutor(el);
+ roomplanner.initDelete(el);
+ roomplanner.initPcButtons(el);
}
}
diff --git a/modules-available/roomplanner/lang/de/module.json b/modules-available/roomplanner/lang/de/module.json
index 58dac918..ef47cdd2 100644
--- a/modules-available/roomplanner/lang/de/module.json
+++ b/modules-available/roomplanner/lang/de/module.json
@@ -1,4 +1,4 @@
{
- "module_name": "PVS-Manager",
- "page_title": "PVS-Manager"
+ "module_name": "Raumplaner",
+ "page_title": "Raumplaner"
} \ No newline at end of file
diff --git a/modules-available/roomplanner/lang/de/permissions.json b/modules-available/roomplanner/lang/de/permissions.json
new file mode 100644
index 00000000..1683c77b
--- /dev/null
+++ b/modules-available/roomplanner/lang/de/permissions.json
@@ -0,0 +1,3 @@
+{
+ "edit": "Raumplan bearbeiten"
+} \ No newline at end of file
diff --git a/modules-available/roomplanner/lang/en/module.json b/modules-available/roomplanner/lang/en/module.json
new file mode 100644
index 00000000..2eb0d069
--- /dev/null
+++ b/modules-available/roomplanner/lang/en/module.json
@@ -0,0 +1,4 @@
+{
+ "module_name": "Roomplanner",
+ "page_title": "Roomplanner"
+} \ No newline at end of file
diff --git a/modules-available/roomplanner/lang/en/permissions.json b/modules-available/roomplanner/lang/en/permissions.json
new file mode 100644
index 00000000..a4a4c54e
--- /dev/null
+++ b/modules-available/roomplanner/lang/en/permissions.json
@@ -0,0 +1,3 @@
+{
+ "edit": "Edit roomplan"
+} \ No newline at end of file
diff --git a/modules-available/roomplanner/page.inc.php b/modules-available/roomplanner/page.inc.php
index 764d5cdb..8b75499b 100644
--- a/modules-available/roomplanner/page.inc.php
+++ b/modules-available/roomplanner/page.inc.php
@@ -30,7 +30,7 @@ class Page_Roomplanner extends Page
{
User::load();
- if (!User::hasPermission('superadmin')) {
+ if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
@@ -79,13 +79,23 @@ class Page_Roomplanner extends Page
$subnetMachines = $this->getPotentialMachines();
$machinesOnPlan = $this->getMachinesOnPlan($config['tutoruuid']);
$roomConfig = array_merge($furniture, $machinesOnPlan);
- Render::addTemplate('page', [
+ $canEdit = User::hasPermission('edit', $this->locationid);
+ $params = [
'location' => $this->location,
'managerip' => $managerIp,
'dediMgrChecked' => $dediMgr,
'subnetMachines' => json_encode($subnetMachines),
'locationid' => $this->locationid,
- 'roomConfiguration' => json_encode($roomConfig)]);
+ 'roomConfiguration' => json_encode($roomConfig),
+ 'edit_disabled' => $canEdit ? '' : 'disabled',
+ 'statistics_disabled' => Module::get('statistics') !== false && User::hasPermission('.statistics.machine.view-details') ? '' : 'disabled',
+ ];
+ Render::addTemplate('header', $params);
+ if ($canEdit) {
+ Render::addTemplate('item-selector', $params);
+ }
+ Render::addTemplate('main-roomplan', $params);
+ Render::addTemplate('footer', $params);
} else {
Message::addError('main.invalid-action', $this->action);
}
@@ -97,16 +107,31 @@ class Page_Roomplanner extends Page
$this->action = Request::any('action', false, 'string');
if ($this->action === 'getmachines') {
+
+ User::load();
+ $locations = User::getAllowedLocations('edit');
+ if (empty($locations)) {
+ die('{"machines":[]}');
+ }
+
$query = Request::get('query', false, 'string');
$aquery = preg_replace('/[^\x01-\x7f]+/', '%', $query);
+ if (strlen(str_replace('%', '', $aquery)) < 2) {
+ $aquery = $query;
+ }
+
+ $condition = 'locationid IN (:locations)';
+ if (in_array(0, $locations)) {
+ $condition .= ' OR locationid IS NULL';
+ }
- $result = Database::simpleQuery('SELECT machineuuid, macaddr, clientip, hostname, fixedlocationid '
- . 'FROM machine '
- . 'WHERE machineuuid LIKE :aquery '
- . ' OR macaddr LIKE :aquery '
- . ' OR clientip LIKE :aquery '
- . ' OR hostname LIKE :query '
- . ' LIMIT 100', ['query' => "%$query%", 'aquery' => "%$aquery%"]);
+ $result = Database::simpleQuery("SELECT machineuuid, macaddr, clientip, hostname, fixedlocationid
+ FROM machine
+ WHERE ($condition) AND machineuuid LIKE :aquery
+ OR macaddr LIKE :aquery
+ OR clientip LIKE :aquery
+ OR hostname LIKE :query
+ LIMIT 100", ['query' => "%$query%", 'aquery' => "%$aquery%", 'locations' => $locations]);
$returnObject = ['machines' => []];
@@ -134,7 +159,7 @@ class Page_Roomplanner extends Page
private function handleSaveRequest($isAjax)
{
- /* save */
+ User::assertPermission('edit', $this->locationid);
$machinesOnPlan = $this->getMachinesOnPlan('invalid');
$config = Request::post('serializedRoom', null, 'string');
$config = json_decode($config, true);
diff --git a/modules-available/roomplanner/permissions/permissions.json b/modules-available/roomplanner/permissions/permissions.json
new file mode 100644
index 00000000..6a520a89
--- /dev/null
+++ b/modules-available/roomplanner/permissions/permissions.json
@@ -0,0 +1,5 @@
+{
+ "edit": {
+ "location-aware": true
+ }
+} \ No newline at end of file
diff --git a/modules-available/roomplanner/style.css b/modules-available/roomplanner/style.css
index 6a68a444..f1dd994a 100644
--- a/modules-available/roomplanner/style.css
+++ b/modules-available/roomplanner/style.css
@@ -701,21 +701,15 @@ ul.toollist li {
display:none;
float: right;}
-.rotationHandle,
-.tutorHandle {
+.pcHandle {
display:none;
float: left;}
-div.draggable:hover .rotationHandle,
-div.draggable:hover .tutorHandle{
+div.ui-draggable:hover > .deleteHandle,
+div.ui-draggable:hover > .pcHandle {
display:inline;
cursor: pointer;}
-div.draggable:hover .deleteHandle {
- display:inline;
- cursor: pointer;}
-
-
[itemtype="furniture"], [itemtype="furniture_drag"] {
z-index: 99;
background-size: 100% 100%;}
diff --git a/modules-available/roomplanner/templates/footer.html b/modules-available/roomplanner/templates/footer.html
new file mode 100644
index 00000000..3294d5ee
--- /dev/null
+++ b/modules-available/roomplanner/templates/footer.html
@@ -0,0 +1,60 @@
+<div class="pull-left">
+ <div class="input-group" style="width:1px">
+ <div class="input-group-addon">{{lang_managerIp}}</div>
+ <input class="form-control" type="text" id="manager-ip" value="{{managerip}}" placeholder="1.2.3.4"
+ style="width:120px" {{edit_disabled}}>
+ <div class="input-group-addon checkbox">
+ <input id="dedi-mgr" type="checkbox" {{dediMgrChecked}} {{edit_disabled}}>
+ <label for="dedi-mgr">{{lang_dedicatedManager}}</label>
+ </div>
+ </div>
+</div>
+<div class="pull-right">
+ <button class="btn btn-default" onclick="triggerCancel()">{{lang_cancel}}</button>
+ <button id="saveBtn" class="btn btn-primary" {{edit_disabled}}>{{lang_save}}</button>
+</div>
+<div class="clearfix"></div>
+
+
+<script type="application/javascript"><!--
+var locationId = '{{locationid}}';
+var subnetMachines, roomConfiguration;
+var plannerLoadState = 'invalid';
+const PLANNER_READ_ONLY = '{{edit_disabled}}'.length !== 0;
+const CAN_OPEN_STATS = '{{statistics_disabled}}'.length === 0;
+document.addEventListener("DOMContentLoaded", function () {
+
+ subnetMachines = makeCombinedField({{{subnetMachines}}});
+ roomConfiguration = {{{roomConfiguration}}};
+
+ $.when(
+ $.getScript("modules/roomplanner/js/lib/jquery-collision.js"),
+ $.getScript("modules/roomplanner/js/lib/jquery-ui-draggable-collision.js"),
+ $.getScript("modules/roomplanner/js/grid.js"),
+ $.Deferred(function( deferred ){
+ $( deferred.resolve );
+ })
+ ).done(function() {
+ $.getScript("modules/roomplanner/js/init.js", function() {
+ initRoomplanner();
+ loadRoom();
+ });
+ });
+});
+
+function loadRoom() {
+ roomplanner.load(roomConfiguration); // TODO: Filter invalid PCs, they're currently invisible and cannot be removed
+ plannerLoadState = roomplanner.serialize();
+}
+
+function triggerCancel() {
+ if (roomplanner.serialize() !== plannerLoadState) {
+ if (!confirm('{{lang_confirmDiscardChanges}}'))
+ return;
+ }
+ window.close();
+ // In case this page wasn't opened via JS, it will not close on modern browsers, so let's reset
+ loadRoom();
+}
+
+// --></script>
diff --git a/modules-available/roomplanner/templates/header.html b/modules-available/roomplanner/templates/header.html
new file mode 100644
index 00000000..5706c970
--- /dev/null
+++ b/modules-available/roomplanner/templates/header.html
@@ -0,0 +1,49 @@
+<!-- Modal -->
+<div class="modal fade" id="selectMachineModal" role="dialog">
+ <div class="modal-dialog">
+
+ <!-- Modal content-->
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">&times;</button>
+ <h4>{{lang_titleAddMachine}}</h4>
+ </div>
+ <div class="modal-body">
+ <ul class="nav nav-tabs">
+ <li class="active"><a data-toggle="tab" href="#subnet">{{lang_titleBySubnet}}</a></li>
+ <li><a data-toggle="tab" href="#search">{{lang_titleBySearch}}</a></li>
+ </ul>
+ <div class="tab-content">
+ <div id="subnet" class="tab-pane fade in active">
+ <br/>
+ <p>
+ {{lang_descriptionBySubnet}}
+ </p>
+ <label for="subnetBox">{{lang_labelBySubnet}}</label>
+ <input id="subnetBox" class="form-control"/>
+ </div>
+ <div id="search" class="tab-pane fade">
+ <br/>
+ <p> {{lang_descriptionBySearch}}</p>
+ <label for="machineSearchBox">{{lang_labelBySearch}}</label>
+ <input id="machineSearchBox" class="form-control"/>
+ </div>
+
+ </div>
+
+
+ </div>
+ <div class="modal-footer">
+ <button class="btn btn-default pull-left" data-dismiss="modal">{{lang_cancel}}</button>
+ <button class="btn btn-primary" id="selectMachineButton" {{edit_disabled}}>{{lang_select}}</button>
+ </div>
+ </div>
+ </div>
+</div>
+
+<!-- berryous raumplaner -->
+<h1>{{lang_roomplanner}} – {{location.locationname}}</h1>
+
+<div class="alert alert-danger" style="display:none" id="error-msg"></div>
+<div class="alert alert-success" style="display:none" id="success-msg">{{lang_planSuccessfullySaved}}</div>
+<div class="alert alert-info" style="display:none" id="saving-msg">{{lang_planBeingSaved}}</div> \ No newline at end of file
diff --git a/modules-available/roomplanner/templates/item-selector.html b/modules-available/roomplanner/templates/item-selector.html
new file mode 100644
index 00000000..72607e7c
--- /dev/null
+++ b/modules-available/roomplanner/templates/item-selector.html
@@ -0,0 +1,314 @@
+<div id="toolpanel" class="panel panel-default" style="z-index:200;">
+ <div class="panel-body">
+ <ul role="tablist" class="nav nav-tabs">
+ <li role="presentation" class="active"><a href="#computers"
+ aria-controls="computers" role="tab"
+ data-toggle="tab">{{lang_catComputers}}</a></li>
+ <li role="presentation"><a href="#walls"
+ aria-controls="walls" role="tab" data-toggle="tab">{{lang_catWalls}}</a></li>
+ <li role="presentation"><a href="#electricaldevices"
+ aria-controls="electricaldevices" role="tab"
+ data-toggle="tab">{{lang_catElectricalDevices}}</a></li>
+ <li role="presentation"><a href="#tables"
+ aria-controls="tables" role="tab" data-toggle="tab">{{lang_catTables}}</a></li>
+ <li role="presentation"><a href="#chairs"
+ aria-controls="chairs" role="tab" data-toggle="tab">{{lang_catChairs}}</a></li>
+ <li role="presentation"><a href="#furniture"
+ aria-controls="furniture" role="tab" data-toggle="tab">{{lang_catFurniture}}</a>
+ </li>
+ <li role="presentation"><a href="#officesupply"
+ aria-controls="officesupply" role="tab"
+ data-toggle="tab">{{lang_catOfficeSupply}}</a></li>
+ <li role="presentation"><a href="#plants"
+ aria-controls="plants" role="tab" data-toggle="tab">{{lang_catPlants}}</a></li>
+ <li role="presentation"><a href="#misc"
+ aria-controls="misc" role="tab" data-toggle="tab">{{lang_catMisc}}</a></li>
+ </ul>
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane" id="walls">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" scalable="h" itemlook="wall-horizontal" class="draggable"
+ style="width:100px; height:25px;" data-height="25" data-width="100"
+ title="Wand (horizontal)"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" scalable="v" itemlook="wall-vertical" class="draggable"
+ style="width:25px; height:100px;" data-height="100" data-width="25" title="Wand (vertial)"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" scalable="h" itemlook="window-horizontal" class="draggable"
+ style="width:50px; height:25px;" data-height="25" data-width="50" title="Fenster"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" scalable="v" itemlook="window-vertical" class="draggable"
+ style="width:25px; height:50px;" data-height="50" data-width="25" title="Fenster"></div>
+ </li>
+
+
+ <li>
+ <div itemtype="furniture" itemlook="door-nw" class="draggable" style="width:50px; height:100px;"
+ data-height="100" data-width="50" title="{{lang_door}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="door-ne" class="draggable" style="width:50px; height:100px;"
+ data-height="100" data-width="50" title="{{lang_door}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="door-sw" class="draggable" style="width:50px; height:100px;"
+ data-height="100" data-width="50" title="{{lang_door}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="door-se" class="draggable" style="width:50px; height:100px;"
+ data-height="100" data-width="50" title="{{lang_door}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="door-wn" class="draggable" style="width:100px; height:50px;"
+ data-height="50" data-width="100" title="{{lang_door}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="door-ws" class="draggable" style="width:100px; height:50px;"
+ data-height="50" data-width="100" title="{{lang_door}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="door-en" class="draggable" style="width:100px; height:50px;"
+ data-height="50" data-width="100" title="{{lang_door}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="door-es" class="draggable" style="width:100px; height:50px;"
+ data-height="50" data-width="100" title="{{lang_door}}"></div>
+ </li>
+
+ </ul>
+ </div>
+
+
+ <div role="tabpanel" class="tab-pane active" id="computers">
+ <ul class="toollist">
+ <li>
+ <div itemtype="pc" itemlook="pc-south" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="PC" noresize=1></div>
+ </li>
+ <li>
+ <div itemtype="pc" itemlook="copier" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="{{lang_photocopier}}" noresize=1></div>
+ </li>
+ <li>
+ <div itemtype="pc" itemlook="printer" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="{{lang_printer}}" noresize=1></div>
+ </li>
+ <li>
+ <div itemtype="pc" itemlook="telephone" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="{{lang_telephone}}" noresize=1></div>
+ </li>
+ </ul>
+ </div>
+
+ <div role="tabpanel" class="tab-pane" id="electricaldevices">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" itemlook="flatscreen" class="draggable" style="width:75px; height:100px;"
+ data-height="100" data-width="75" title="{{lang_flatscreen}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="lamp" class="draggable" style="width:125px; height:50px;"
+ data-height="50" data-width="125" title="{{lang_deskLamp}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="tvcamera" class="draggable" style="width:125px; height:50px;"
+ data-height="50" data-width="125" title="{{lang_projector}}"></div>
+ </li>
+ </ul>
+ </div>
+
+ <div role="tabpanel" class="tab-pane" id="tables">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" itemlook="4chairs1squaretable" class="draggable"
+ style="width:100px; height:100px;" data-height="100" data-width="100"
+ title="{{lang_4chairs1squaretable}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="6chairs1table-horizontal" class="draggable"
+ style="width:100px; height:75px;" data-height="75" data-width="100"
+ title="{{lang_6chairs1table}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="8chairs1conferencetable-horizontal" class="draggable"
+ style="width:175px; height:100px;" data-height="100" data-width="175"
+ title="{{lang_8chairs1conferencetable}}"></div>
+ </li>
+
+ <li>
+ <div itemtype="furniture" itemlook="classroomdesk-north" class="draggable"
+ style="width:275px; height:100px;" data-height="100" data-width="275"
+ title="{{lang_classroomdesk}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="classroomdeskchair-north" class="draggable"
+ style="width:175px; height:100px;" data-height="100" data-width="175"
+ title="{{lang_classroomdeskchair}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="classroomtable-east" class="draggable"
+ style="width:75px; height:100px;" data-height="100" data-width="75"
+ title="{{lang_classroomtable}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="classroomtablechair-north" class="draggable"
+ style="width:75px; height:100px;" data-height="100" data-width="75"
+ title="{{lang_classroomdeskchair}}"></div>
+ </li>
+
+ <li>
+ <div itemtype="furniture" itemlook="conferencetable-horizontal" class="draggable"
+ style="width:200px; height:100px;" data-height="100" data-width="200"
+ title="{{lang_conferencetable}}"></div>
+ </li>
+
+
+ <li>
+ <div itemtype="furniture" itemlook="podium-north" class="draggable" style="width:200px; height:100px;"
+ data-height="100" data-width="200" title="{{lang_podium}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="roundeddesk-east" class="draggable"
+ style="width:75px; height:100px;" data-height="100" data-width="75"
+ title="{{lang_roundeddesk}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="roundtable" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="{{lang_roundtable}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="semicirculartable-north" class="draggable"
+ style="width:200px; height:100px;" data-height="100" data-width="200"
+ title="{{lang_semicirculartable}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="squaretable" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="{{lang_squaretable}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="studentdesk-north" class="draggable"
+ style="width:150px; height:100px;" data-height="100" data-width="150"
+ title="{{lang_studentdesk}}"></div>
+ </li>
+
+
+ </ul>
+
+ </div>
+
+ <div role="tabpanel" class="tab-pane" id="chairs">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" itemlook="armchair-south" class="draggable"
+ style="width:100px; height:100px;" data-height="100" data-width="100"
+ title="{{lang_armchair}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="chair-south" class="draggable" style="width:125px; height:100px;"
+ data-height="100" data-width="125" title="{{lang_chair}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="chair2-south" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="{{lang_chair}}"></div>
+ </li>
+
+
+ <li>
+ <div itemtype="furniture" itemlook="couch-south" class="draggable" style="width:100px; height:100px;"
+ data-height="100" data-width="100" title="{{lang_couch}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="greenchair-south" class="draggable"
+ style="width:125px; height:100px;" data-height="100" data-width="125"
+ title="{{lang_greenchair}}"></div>
+ </li>
+
+ <li>
+ <div itemtype="furniture" itemlook="studentdeskchair-north" class="draggable"
+ style="width:100px; height:100px;" data-height="100" data-width="100"
+ title="{{lang_studentdeskchair}}"></div>
+ </li>
+ </ul>
+ </div>
+
+ <div role="tabpanel" class="tab-pane" id="furniture">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" itemlook="locker-east" class="draggable" style="width:100px; height:75px;"
+ data-height="75" data-width="100" title="{{lang_locker}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="locker-north" class="draggable" style="width:75px; height:100px;"
+ data-height="100" data-width="75" title="{{lang_locker}}"></div>
+ </li>
+
+ <li>
+ <div itemtype="furniture" itemlook="coatrack-east" class="draggable" style="width:25px; height:150px;"
+ data-height="150" data-width="25" title="{{lang_coatrack}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="coatrack-north" class="draggable"
+ style="width:150px; height:25px;" data-height="25" data-width="150"
+ title="{{lang_coatrack}}"></div>
+ </li>
+
+
+ <li>
+ <div itemtype="furniture" itemlook="lecturetheaterrow" class="draggable"
+ style="width:725px; height:100px;" data-height="100" data-width="725"
+ title="{{lang_lecturetheaterrow}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="lecturetheaterrowseats" class="draggable"
+ style="width:725px; height:50px;" data-height="50" data-width="725"
+ title="{{lang_lecturetheaterrow}}"></div>
+ </li>
+
+ </ul>
+ </div>
+
+ <div role="tabpanel" class="tab-pane" id="officesupply">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" itemlook="papertray" class="draggable" style="width:25px; height:50px;"
+ data-height="50" data-width="25" title="{{lang_papertray}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="wastecan" class="draggable" style="width:50px; height:50px;"
+ data-height="50" data-width="50" title="{{lang_wastecan}}"></div>
+ </li>
+
+ </ul>
+ </div>
+ <div role="tabpanel" class="tab-pane" id="plants">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" itemlook="plant" class="draggable" style="width:75px; height:75px;"
+ data-height="75" data-width="75" title="{{lang_plant}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="plant2" class="draggable" style="width:75px; height:75px;"
+ data-height="75" data-width="75" title="{{lang_plant}}"></div>
+ </li>
+ <li>
+ <div itemtype="furniture" itemlook="plant3" class="draggable" style="width:75px; height:75px;"
+ data-height="75" data-width="75" title="{{lang_plant}}"></div>
+ </li>
+ </ul>
+ </div>
+ <div role="tabpanel" class="tab-pane" id="misc">
+ <ul class="toollist">
+ <li>
+ <div itemtype="furniture" itemlook="projectionscreen" class="draggable"
+ style="width:525px; height:25px;" data-height="25" data-width="525" title="{{lang_plant}}"></div>
+ </li>
+ </ul>
+ </div>
+
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules-available/roomplanner/templates/main-roomplan.html b/modules-available/roomplanner/templates/main-roomplan.html
new file mode 100644
index 00000000..1fc49bea
--- /dev/null
+++ b/modules-available/roomplanner/templates/main-roomplan.html
@@ -0,0 +1,18 @@
+<div class="panel panel-default" id="drawpanel">
+ <div class="panel-heading">
+ <h3 class="panel-title">{{lang_roomplan}}</h3>
+ </div>
+ <div class="panel-body">
+ <div id="drawarea" style="top:0px; left:0px;">
+ <div id="draw-element-area" style="width:100%; height:100%;"></div>
+ </div>
+ <div id="scaleContainer">
+ <span id="zoom-fit" class="glyphicon glyphicon-move" aria-hidden="true"></span>
+ <div>
+ <div id="scaleslider"></div>
+ <span id="zoom-out" class="glyphicon glyphicon-zoom-out" aria-hidden="true"></span>
+ <span id="zoom-in" class="glyphicon glyphicon-zoom-in" aria-hidden="true"></span>
+ </div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules-available/roomplanner/templates/page.html b/modules-available/roomplanner/templates/page.html
deleted file mode 100644
index e8544ce8..00000000
--- a/modules-available/roomplanner/templates/page.html
+++ /dev/null
@@ -1,369 +0,0 @@
-<!-- Modal -->
-<div class="modal fade" id="selectMachineModal" role="dialog">
- <div class="modal-dialog">
-
- <!-- Modal content-->
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal">&times;</button>
- <h4>{{lang_titleAddMachine}}</h4>
- </div>
- <div class="modal-body">
- <ul class="nav nav-tabs">
- <li class="active"><a data-toggle="tab" href="#subnet">{{lang_titleBySubnet}}</a></li>
- <li><a data-toggle="tab" href="#search">{{lang_titleBySearch}}</a></li>
- </ul>
- <div class="tab-content">
- <div id="subnet" class="tab-pane fade in active">
- <br/>
- <p>
- {{lang_descriptionBySubnet}}
- </p>
- <label for="subnetBox">{{lang_labelBySubnet}}</label>
- <input id="subnetBox" class="form-control"/>
- </div>
- <div id="search" class="tab-pane fade">
- <br/>
- <p> {{lang_descriptionBySearch}}</p>
- <label for="machineSearchBox">{{lang_labelBySearch}}</label>
- <input id="machineSearchBox" class="form-control" />
- </div>
-
- </div>
-
-
- </div>
- <div class="modal-footer">
- <button class="btn btn-default pull-left" data-dismiss="modal" >{{lang_cancel}}</button>
- <button class="btn btn-primary" id="selectMachineButton">{{lang_select}}</button>
- </div>
- </div>
- </div>
-</div>
-
-<!-- berryous raumplaner -->
-<h1>{{lang_roomplanner}} – {{location.locationname}}</h1>
-
-<div class="alert alert-danger" style="display:none" id="error-msg"></div>
-<div class="alert alert-success" style="display:none" id="success-msg">{{lang_planSuccessfullySaved}}</div>
-<div class="alert alert-info" style="display:none" id="saving-msg">{{lang_planBeingSaved}}</div>
-
- <div id="toolpanel" class="panel panel-default" style="z-index:200;">
- <div class="panel-body">
- <ul role="tablist" class="nav nav-tabs">
- <li role="presentation" class="active"><a href="#computers"
- aria-controls="computers" role="tab" data-toggle="tab">{{lang_catComputers}}</a></li>
- <li role="presentation"><a href="#walls"
- aria-controls="walls" role="tab" data-toggle="tab">{{lang_catWalls}}</a></li>
- <li role="presentation"><a href="#electricaldevices"
- aria-controls="electricaldevices" role="tab" data-toggle="tab">{{lang_catElectricalDevices}}</a></li>
- <li role="presentation"><a href="#tables"
- aria-controls="tables" role="tab" data-toggle="tab">{{lang_catTables}}</a></li>
- <li role="presentation"><a href="#chairs"
- aria-controls="chairs" role="tab" data-toggle="tab">{{lang_catChairs}}</a></li>
- <li role="presentation"><a href="#furniture"
- aria-controls="furniture" role="tab" data-toggle="tab">{{lang_catFurniture}}</a></li>
- <li role="presentation"><a href="#officesupply"
- aria-controls="officesupply" role="tab" data-toggle="tab">{{lang_catOfficeSupply}}</a></li>
- <li role="presentation"><a href="#plants"
- aria-controls="plants" role="tab" data-toggle="tab">{{lang_catPlants}}</a></li>
- <li role="presentation"><a href="#misc"
- aria-controls="misc" role="tab" data-toggle="tab">{{lang_catMisc}}</a></li>
- </ul>
- <div class="tab-content">
- <div role="tabpanel" class="tab-pane" id="walls">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" scalable="h" itemlook="wall-horizontal" class="draggable" style="width:100px; height:25px;" data-height="25" data-width="100" title="Wand (horizontal)"></div>
- </li>
- <li>
- <div itemtype="furniture" scalable="v" itemlook="wall-vertical" class="draggable" style="width:25px; height:100px;" data-height="100" data-width="25" title="Wand (vertial)"></div>
- </li>
- <li>
- <div itemtype="furniture" scalable="h" itemlook="window-horizontal" class="draggable" style="width:50px; height:25px;" data-height="25" data-width="50" title="Fenster"></div>
- </li>
- <li>
- <div itemtype="furniture" scalable="v" itemlook="window-vertical" class="draggable" style="width:25px; height:50px;" data-height="50" data-width="25" title="Fenster"></div>
- </li>
-
-
- <li>
- <div itemtype="furniture" itemlook="door-nw" class="draggable" style="width:50px; height:100px;" data-height="100" data-width="50" title="{{lang_door}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="door-ne" class="draggable" style="width:50px; height:100px;" data-height="100" data-width="50" title="{{lang_door}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="door-sw" class="draggable" style="width:50px; height:100px;" data-height="100" data-width="50" title="{{lang_door}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="door-se" class="draggable" style="width:50px; height:100px;" data-height="100" data-width="50" title="{{lang_door}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="door-wn" class="draggable" style="width:100px; height:50px;" data-height="50" data-width="100" title="{{lang_door}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="door-ws" class="draggable" style="width:100px; height:50px;" data-height="50" data-width="100" title="{{lang_door}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="door-en" class="draggable" style="width:100px; height:50px;" data-height="50" data-width="100" title="{{lang_door}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="door-es" class="draggable" style="width:100px; height:50px;" data-height="50" data-width="100" title="{{lang_door}}"></div>
- </li>
-
- </ul>
- </div>
-
-
- <div role="tabpanel" class="tab-pane active" id="computers">
- <ul class="toollist">
- <li>
- <div itemtype="pc" itemlook="pc-south" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="PC" noresize=1></div>
- </li>
- <li>
- <div itemtype="pc" itemlook="copier" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_photocopier}}" noresize=1></div>
- </li>
- <li>
- <div itemtype="pc" itemlook="printer" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_printer}}" noresize=1></div>
- </li>
- <li>
- <div itemtype="pc" itemlook="telephone" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_telephone}}" noresize=1></div>
- </li>
- </ul>
- </div>
-
- <div role="tabpanel" class="tab-pane" id="electricaldevices">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" itemlook="flatscreen" class="draggable" style="width:75px; height:100px;" data-height="100" data-width="75" title="{{lang_flatscreen}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="lamp" class="draggable" style="width:125px; height:50px;" data-height="50" data-width="125" title="{{lang_deskLamp}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="tvcamera" class="draggable" style="width:125px; height:50px;" data-height="50" data-width="125" title="{{lang_projector}}"></div>
- </li>
- </ul>
- </div>
-
- <div role="tabpanel" class="tab-pane" id="tables">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" itemlook="4chairs1squaretable" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_4chairs1squaretable}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="6chairs1table-horizontal" class="draggable" style="width:100px; height:75px;" data-height="75" data-width="100" title="{{lang_6chairs1table}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="8chairs1conferencetable-horizontal" class="draggable" style="width:175px; height:100px;" data-height="100" data-width="175" title="{{lang_8chairs1conferencetable}}"></div>
- </li>
-
- <li>
- <div itemtype="furniture" itemlook="classroomdesk-north" class="draggable" style="width:275px; height:100px;" data-height="100" data-width="275" title="{{lang_classroomdesk}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="classroomdeskchair-north" class="draggable" style="width:175px; height:100px;" data-height="100" data-width="175" title="{{lang_classroomdeskchair}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="classroomtable-east" class="draggable" style="width:75px; height:100px;" data-height="100" data-width="75" title="{{lang_classroomtable}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="classroomtablechair-north" class="draggable" style="width:75px; height:100px;" data-height="100" data-width="75" title="{{lang_classroomdeskchair}}"></div>
- </li>
-
- <li>
- <div itemtype="furniture" itemlook="conferencetable-horizontal" class="draggable" style="width:200px; height:100px;" data-height="100" data-width="200" title="{{lang_conferencetable}}"></div>
- </li>
-
-
- <li>
- <div itemtype="furniture" itemlook="podium-north" class="draggable" style="width:200px; height:100px;" data-height="100" data-width="200" title="{{lang_podium}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="roundeddesk-east" class="draggable" style="width:75px; height:100px;" data-height="100" data-width="75" title="{{lang_roundeddesk}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="roundtable" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_roundtable}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="semicirculartable-north" class="draggable" style="width:200px; height:100px;" data-height="100" data-width="200" title="{{lang_semicirculartable}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="squaretable" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_squaretable}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="studentdesk-north" class="draggable" style="width:150px; height:100px;" data-height="100" data-width="150" title="{{lang_studentdesk}}"></div>
- </li>
-
-
- </ul>
-
- </div>
-
- <div role="tabpanel" class="tab-pane" id="chairs">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" itemlook="armchair-south" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_armchair}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="chair-south" class="draggable" style="width:125px; height:100px;" data-height="100" data-width="125" title="{{lang_chair}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="chair2-south" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_chair}}"></div>
- </li>
-
-
- <li>
- <div itemtype="furniture" itemlook="couch-south" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_couch}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="greenchair-south" class="draggable" style="width:125px; height:100px;" data-height="100" data-width="125" title="{{lang_greenchair}}"></div>
- </li>
-
- <li>
- <div itemtype="furniture" itemlook="studentdeskchair-north" class="draggable" style="width:100px; height:100px;" data-height="100" data-width="100" title="{{lang_studentdeskchair}}"></div>
- </li>
- </ul>
- </div>
-
- <div role="tabpanel" class="tab-pane" id="furniture">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" itemlook="locker-east" class="draggable" style="width:100px; height:75px;" data-height="75" data-width="100" title="{{lang_locker}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="locker-north" class="draggable" style="width:75px; height:100px;" data-height="100" data-width="75" title="{{lang_locker}}"></div>
- </li>
-
- <li>
- <div itemtype="furniture" itemlook="coatrack-east" class="draggable" style="width:25px; height:150px;" data-height="150" data-width="25" title="{{lang_coatrack}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="coatrack-north" class="draggable" style="width:150px; height:25px;" data-height="25" data-width="150" title="{{lang_coatrack}}"></div>
- </li>
-
-
- <li>
- <div itemtype="furniture" itemlook="lecturetheaterrow" class="draggable" style="width:725px; height:100px;" data-height="100" data-width="725" title="{{lang_lecturetheaterrow}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="lecturetheaterrowseats" class="draggable" style="width:725px; height:50px;" data-height="50" data-width="725" title="{{lang_lecturetheaterrow}}"></div>
- </li>
-
- </ul>
- </div>
-
- <div role="tabpanel" class="tab-pane" id="officesupply">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" itemlook="papertray" class="draggable" style="width:25px; height:50px;" data-height="50" data-width="25" title="{{lang_papertray}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="wastecan" class="draggable" style="width:50px; height:50px;" data-height="50" data-width="50" title="{{lang_wastecan}}"></div>
- </li>
-
- </ul>
- </div>
- <div role="tabpanel" class="tab-pane" id="plants">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" itemlook="plant" class="draggable" style="width:75px; height:75px;" data-height="75" data-width="75" title="{{lang_plant}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="plant2" class="draggable" style="width:75px; height:75px;" data-height="75" data-width="75" title="{{lang_plant}}"></div>
- </li>
- <li>
- <div itemtype="furniture" itemlook="plant3" class="draggable" style="width:75px; height:75px;" data-height="75" data-width="75" title="{{lang_plant}}"></div>
- </li>
- </ul>
- </div>
- <div role="tabpanel" class="tab-pane" id="misc">
- <ul class="toollist">
- <li>
- <div itemtype="furniture" itemlook="projectionscreen" class="draggable" style="width:525px; height:25px;" data-height="25" data-width="525" title="{{lang_plant}}"></div>
- </li>
- </ul>
- </div>
-
- </div>
- </div>
- </div>
-
-
-
- <div class="panel panel-default" id="drawpanel">
- <div class="panel-heading">
- <h3 class="panel-title">{{lang_roomplan}}</h3>
- </div>
- <div class="panel-body">
- <div id="drawarea" style="top:0px; left:0px;">
- <div id="draw-element-area" style="width:100%; height:100%;"></div>
- </div>
- <div id="scaleContainer">
- <span id="zoom-fit" class="glyphicon glyphicon-move" aria-hidden="true"></span>
- <div>
- <div id="scaleslider"></div>
- <span id="zoom-out" class="glyphicon glyphicon-zoom-out" aria-hidden="true"></span>
- <span id="zoom-in" class="glyphicon glyphicon-zoom-in" aria-hidden="true"></span>
- </div>
- </div>
- </div>
-
-
- </div>
-
-<div class="pull-left">
- <div class="input-group" style="width:1px">
- <div class="input-group-addon">{{lang_managerIp}}</div>
- <input class="form-control" type="text" id="manager-ip" value="{{managerip}}" placeholder="1.2.3.4" style="width:120px">
- <div class="input-group-addon checkbox"><input id="dedi-mgr" type="checkbox" {{dediMgrChecked}}> <label for="dedi-mgr">{{lang_dedicatedManager}}</label></div>
- </div>
-</div>
-<div class="pull-right">
- <button class="btn btn-default" onclick="triggerCancel()">{{lang_cancel}}</button>
- <button id="saveBtn" class="btn btn-primary">{{lang_save}}</button>
-</div>
-<div class="clearfix"></div>
-
-
-<script type="application/javascript"><!--
-var locationId = '{{locationid}}';
-var subnetMachines, roomConfiguration;
-var plannerLoadState = 'invalid';
-document.addEventListener("DOMContentLoaded", function () {
-
- subnetMachines = makeCombinedField({{{subnetMachines}}});
- roomConfiguration = {{{roomConfiguration}}};
-
- $.when(
- $.getScript("modules/roomplanner/js/lib/jquery-collision.js"),
- $.getScript("modules/roomplanner/js/lib/jquery-ui-draggable-collision.js"),
- $.getScript("modules/roomplanner/js/grid.js"),
- $.Deferred(function( deferred ){
- $( deferred.resolve );
- })
- ).done(function() {
- $.getScript("modules/roomplanner/js/init.js", function() {
- initRoomplanner();
- loadRoom();
- });
- });
-});
-
-function loadRoom() {
- roomplanner.load(roomConfiguration); // TODO: Filter invalid PCs, they're currently invisible and cannot be removed
- plannerLoadState = roomplanner.serialize();
-}
-
-function triggerCancel() {
- if (roomplanner.serialize() !== plannerLoadState) {
- if (!confirm('{{lang_confirmDiscardChanges}}'))
- return;
- }
- window.close();
- // In case this page wasn't opened via JS, it will not close on modern browsers, so let's reset
- loadRoom();
-}
-
-// --></script>
diff --git a/modules-available/runmode/baseconfig/getconfig.inc.php b/modules-available/runmode/baseconfig/getconfig.inc.php
index 2d622fc7..8ea2b2a6 100644
--- a/modules-available/runmode/baseconfig/getconfig.inc.php
+++ b/modules-available/runmode/baseconfig/getconfig.inc.php
@@ -6,21 +6,17 @@ $foofoo = function($machineUuid) {
if ($res === false)
return;
$config = RunMode::getModuleConfig($res['module']);
- if ($config === false || $config->configHook === false)
+ if ($config === false)
return;
if (!Module::isAvailable($res['module']))
return; // Not really possible because getModuleConfig would have failed but we should make sure
- call_user_func($config->configHook, $machineUuid, $res['modeid'], $res['modedata']);
+ if ($config->configHook !== false) {
+ call_user_func($config->configHook, $machineUuid, $res['modeid'], $res['modedata']);
+ }
if ($config->systemdDefaultTarget !== false) {
ConfigHolder::add('SLX_SYSTEMD_TARGET', $config->systemdDefaultTarget, 10000);
}
- // Disable exam mode - not sure if this is generally a good idea; for now, all modes we can think of would
- // not make sense that way so do this for now
- if (ConfigHolder::get('SLX_EXAM') !== false) {
- ConfigHolder::add('SLX_EXAM', '', 100001);
- ConfigHolder::add('SLX_EXAM_START', '', 100001);
- ConfigHolder::add('SLX_AUTOLOGIN', '', 100001);
- }
+ ConfigHolder::add('SLX_RUNMODE_MODULE', $res['module']);
};
$foofoo($uuid); \ No newline at end of file
diff --git a/modules-available/runmode/config.json b/modules-available/runmode/config.json
index e3c07d48..84e044ce 100644
--- a/modules-available/runmode/config.json
+++ b/modules-available/runmode/config.json
@@ -1,4 +1,7 @@
{
- "dependencies": [ "statistics", "js_selectize" ],
- "permission":"0"
-}
+ "dependencies": [
+ "statistics",
+ "js_selectize"
+ ],
+ "permission": "0"
+} \ No newline at end of file
diff --git a/modules-available/runmode/inc/runmode.inc.php b/modules-available/runmode/inc/runmode.inc.php
index 2c8083ca..174fb675 100644
--- a/modules-available/runmode/inc/runmode.inc.php
+++ b/modules-available/runmode/inc/runmode.inc.php
@@ -28,7 +28,7 @@ class RunMode
/**
* @param string $machineuuid
- * @param string $moduleId
+ * @param string|\Module $moduleId
* @param string|null $modeId an ID specific to the module to further specify the run mode, NULL to delete the run mode entry
* @param string|null $modeData optional, additional data for the run mode
* @param bool|null $isClient whether to count the machine as a client (in statistics etc.) NULL for looking at module's general runmode config
@@ -284,6 +284,11 @@ class RunModeModuleConfig
*/
public $deleteUrlSnippet = false;
+ /**
+ * @var string|false Permission to check when accessing/assigning
+ */
+ public $permission = false;
+
public function __construct($file)
{
$data = json_decode(file_get_contents($file), true);
@@ -298,6 +303,7 @@ class RunModeModuleConfig
$this->loadType($data, 'noSysconfig', 'boolean');
$this->loadType($data, 'allowGenericEditor', 'boolean');
$this->loadType($data, 'deleteUrlSnippet', 'string');
+ $this->loadType($data, 'permission', 'string');
}
private function loadType($data, $key, $type)
@@ -311,4 +317,10 @@ class RunModeModuleConfig
$this->{$key} = $data[$key];
return true;
}
+
+ public function userHasPermission($locationId)
+ {
+ return $this->permission === false || User::hasPermission($this->permission, $locationId);
+ }
+
}
diff --git a/modules-available/runmode/lang/de/messages.json b/modules-available/runmode/lang/de/messages.json
index 911d48d4..bca70019 100644
--- a/modules-available/runmode/lang/de/messages.json
+++ b/modules-available/runmode/lang/de/messages.json
@@ -2,6 +2,7 @@
"cannot-edit-module": "Modul {{0}} kann nicht direkt editiert werden",
"enabled-removed-save": "{{0}} Rechner gespeichert, {{1}} entfernt",
"invalid-modeid": "{{1}} ist kein g\u00fcltiger Betriebsmodus f\u00fcr Modul {{0}}",
+ "machine-no-permission": "Keine Berechtigung f\u00fcr client {{0}}",
"machine-not-found": "Rechner {{0}} nicht gefunden",
"machine-not-runmode": "Rechner {{0}} hatte keinen speziellen Betriebsmodus aktiviert",
"machine-removed": "Rechner {{0}} entfernt",
diff --git a/modules-available/runmode/lang/de/module.json b/modules-available/runmode/lang/de/module.json
new file mode 100644
index 00000000..779d303b
--- /dev/null
+++ b/modules-available/runmode/lang/de/module.json
@@ -0,0 +1,4 @@
+{
+ "module_name": "Betriebsmodus",
+ "page_title": "Betriebsmodus"
+}
diff --git a/modules-available/runmode/lang/de/permissions.json b/modules-available/runmode/lang/de/permissions.json
new file mode 100644
index 00000000..0a89e027
--- /dev/null
+++ b/modules-available/runmode/lang/de/permissions.json
@@ -0,0 +1,3 @@
+{
+ "list-all": "Betriebsmodi anzeigen"
+} \ No newline at end of file
diff --git a/modules-available/runmode/lang/de/template-tags.json b/modules-available/runmode/lang/de/template-tags.json
index 6b45b82c..989e5b1d 100644
--- a/modules-available/runmode/lang/de/template-tags.json
+++ b/modules-available/runmode/lang/de/template-tags.json
@@ -3,6 +3,7 @@
"lang_assignMachineIntroText": "Definieren Sie hier Clients, die in einem speziellen Betriebsmodus gestartet werden sollen. Sie k\u00f6nnen Rechner anhand der UUID, IP, Hostname oder MAC-Adresse suchen.",
"lang_assignRunmodeToMachine": "Betriebsmodus",
"lang_confirmDelete": "Wollen Sie den Betriebsmodus f\u00fcr diesen Client entfernen?",
+ "lang_existingClients": "Vorhandene Clients mit diesem Betriebsmodus",
"lang_isclient": "Pool-Client",
"lang_machine": "Client",
"lang_mode": "Modus",
diff --git a/modules-available/runmode/lang/en/messages.json b/modules-available/runmode/lang/en/messages.json
index 6d890428..1ca1567a 100644
--- a/modules-available/runmode/lang/en/messages.json
+++ b/modules-available/runmode/lang/en/messages.json
@@ -2,6 +2,7 @@
"cannot-edit-module": "Module {{0}} cannot be edited directly",
"enabled-removed-save": "Saved {{0}} clients, deleted {{1}}",
"invalid-modeid": "Module {{0}} doesn't provide mode {{1}}",
+ "machine-no-permission": "No permission for client {{0}}",
"machine-not-found": "Client {{0}} not found",
"machine-not-runmode": "No special mode of operation configured for client {{0}}",
"machine-removed": "Removed client {{0}}",
diff --git a/modules-available/runmode/lang/en/module.json b/modules-available/runmode/lang/en/module.json
new file mode 100644
index 00000000..76712161
--- /dev/null
+++ b/modules-available/runmode/lang/en/module.json
@@ -0,0 +1,4 @@
+{
+ "module_name": "Runmode",
+ "page_title": "Runmode"
+}
diff --git a/modules-available/runmode/lang/en/permissions.json b/modules-available/runmode/lang/en/permissions.json
new file mode 100644
index 00000000..8b3a6e62
--- /dev/null
+++ b/modules-available/runmode/lang/en/permissions.json
@@ -0,0 +1,3 @@
+{
+ "list-all": "Show runmodes"
+} \ No newline at end of file
diff --git a/modules-available/runmode/lang/en/template-tags.json b/modules-available/runmode/lang/en/template-tags.json
index 43fd3da5..89cf6b15 100644
--- a/modules-available/runmode/lang/en/template-tags.json
+++ b/modules-available/runmode/lang/en/template-tags.json
@@ -3,6 +3,7 @@
"lang_assignMachineIntroText": "Define the clients which should start a special runmode configuration. You can search for clients by UUID, IP address, host name or MAC address.",
"lang_assignRunmodeToMachine": "Runmode",
"lang_confirmDelete": "Do you want to delete the runmode for this client?",
+ "lang_existingClients": "Existing clients with this run mode",
"lang_isclient": "Pool-Client",
"lang_machine": "Client",
"lang_mode": "Mode",
diff --git a/modules-available/runmode/page.inc.php b/modules-available/runmode/page.inc.php
index b94b8a31..f8b48152 100644
--- a/modules-available/runmode/page.inc.php
+++ b/modules-available/runmode/page.inc.php
@@ -14,79 +14,142 @@ class Page_RunMode extends Page
Util::redirect('?do=main');
}
$action = Request::post('action', false, 'string');
- if ($action !== false) {
- $this->handleAction($action);
+ if ($action === 'save-mode') {
+ $this->handleSaveMode();
+ } elseif ($action === 'delete-machine') {
+ $this->handleDeleteMachine();
+ }
+ if (Request::isPost()) {
Util::redirect('?do=runmode');
}
}
- private function handleAction($action)
+ private function handleSaveMode()
{
- if ($action === 'save-mode') {
- $machines = array_filter(Request::post('machines', [], 'array'), 'is_string');
- $module = Request::post('module', false, 'string');
- $modeId = Request::post('modeid', false, 'string');
- $modConfig = RunMode::getModuleConfig($module);
- if ($modConfig === false) {
- Message::addError('runmode.module-hasnt-runmode', $module);
- return;
- }
- if (!$modConfig->allowGenericEditor) {
- Message::addError('runmode.cannot-edit-module', $module);
- return;
- }
- $test = RunMode::getModeName($module, $modeId);
- if ($test === false) {
- Message::addError('runmode.invalid-modeid', $module, $modeId);
- return;
- }
- $active = 0;
- foreach ($machines as $machine) {
- $oldMode = RunMode::getRunMode($machine, 0);
- if ($oldMode !== false) {
- $oldModule = RunMode::getModuleConfig($oldMode['module']);
- if ($oldModule !== false && (!$oldModule->allowGenericEditor || $oldModule->deleteUrlSnippet !== false)) {
- Message::addError('runmode.machine-still-assigned', $machine, $oldMode['module']);
- continue;
- }
+ $machines = array_unique(array_filter(Request::post('machines', [], 'array'), 'is_string'));
+ $module = Request::post('module', false, 'string');
+ $modeId = Request::post('modeid', false, 'string');
+ $modConfig = RunMode::getModuleConfig($module);
+ if ($modConfig === false) {
+ Message::addError('runmode.module-hasnt-runmode', $module);
+ return;
+ }
+ if (!$modConfig->allowGenericEditor) {
+ Message::addError('runmode.cannot-edit-module', $module);
+ return;
+ }
+ $test = RunMode::getModeName($module, $modeId);
+ if ($test === false) {
+ Message::addError('runmode.invalid-modeid', $module, $modeId);
+ return;
+ }
+ // Query existing entries first (for delete - see below)
+ $existing = [];
+ if ($modConfig->permission !== false) {
+ $existing = RunMode::getForMode($module, $modeId, true, true);
+ }
+ // Before doing anything, check if the user has the proper permission for any location - if not, nothing to do
+ if (!$modConfig->userHasPermission(null)) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=runmode');
+ }
+ $active = 0;
+ foreach ($machines as $machine) {
+ if (isset($existing[$machine])) {
+ if (!$modConfig->userHasPermission($existing[$machine]['locationid'])) {
+ // Machine was already assigned to this runmode, and user has no permission for its location
+ unset($existing[$machine]);
+ continue; // So keep it as-is and skip
}
- $ret = RunMode::setRunMode($machine, $module, $modeId, null, null);
- if ($ret) {
- $active++;
+ // User has permission to add this existing machine, keep going so meta data could be updated
+ unset($existing[$machine]);
+ } else {
+ // Not existing yet in this module/mode combo, but check if it is assigned to some other run mode
+ $machineLocation = false;
+ $oldMachineMode = RunMode::getRunMode($machine, RunMode::DATA_MACHINE_DATA | RunMode::DATA_DETAILED);
+ if ($oldMachineMode !== false) {
+ $machineLocation = $oldMachineMode['locationid'];
+ $oldModule = RunMode::getModuleConfig($oldMachineMode['module']);
+ if ($oldModule !== false) {
+ if ($oldMachineMode['module'] !== $module || $oldMachineMode['modeid'] !== $modeId) {
+ if (!$oldModule->allowGenericEditor || $oldModule->deleteUrlSnippet !== false) {
+ Message::addError('runmode.machine-still-assigned', $machine, $oldMachineMode['module']);
+ continue;
+ }
+ }
+ // Permissions for old runmode
+ if (!$oldModule->userHasPermission($oldMachineMode['locationid'])) {
+ // Show same error message as above - might help the user figure out they have no perm to remove it
+ Message::addError('runmode.machine-still-assigned', $machine, $oldMachineMode['module']);
+ continue;
+ }
+ }
} else {
- Message::addError('runmode.machine-not-found', $machine);
+ // Not existing, no old mode - query machine to get location, so we can do a perm-check for new loc
+ $m = Statistics::getMachine($machine, Machine::NO_DATA);
+ if ($m !== false) {
+ $machineLocation = $m->locationid;
+ }
+ }
+ if ($machineLocation !== false && !$modConfig->userHasPermission($machineLocation)) {
+ Message::addError('runmode.machine-no-permission', $machine);
+ continue;
}
}
+ $ret = RunMode::setRunMode($machine, $module, $modeId, null, null);
+ if ($ret) {
+ $active++;
+ } else {
+ Message::addError('runmode.machine-not-found', $machine);
+ }
+ }
+ // Make sure inaccessible machines (no permission for location) are preserved on delete
+ // Add existing but inaccessible to list
+ foreach ($existing as $e) {
+ if (!$modConfig->userHasPermission($e['locationid'])) {
+ $machines[] = $e['machineuuid'];
+ }
+ }
+ if ($modConfig->deleteUrlSnippet === false) {
$deleted = Database::exec('DELETE FROM runmode
WHERE module = :module AND modeid = :modeId AND machineuuid NOT IN (:machines)',
compact('module', 'modeId', 'machines'));
- Message::addSuccess('runmode.enabled-removed-save', $active, $deleted);
- Util::redirect('?do=runmode&module=' . $module . '&modeid=' . $modeId, true);
- } elseif ($action === 'delete-machine') {
- $machineuuid = Request::post('machineuuid', false, 'string');
- if ($machineuuid === false) {
- Message::addError('main.parameter-missing', 'machineuuid');
- return;
- }
- $mode = RunMode::getRunMode($machineuuid);
- if ($mode === false) {
- Message::addError('runmode.machine-not-found', $machineuuid);
- return;
- }
- $modConfig = RunMode::getModuleConfig($mode['module']);
- if ($modConfig === false) {
- Message::addError('module-hasnt-runmode', $mode['moduleName']);
- return;
- }
- if (!$modConfig->allowGenericEditor) {
- Message::addError('runmode.cannot-edit-module', $mode['moduleName']);
- return;
- }
- if (RunMode::setRunMode($machineuuid, null, null)) {
- Message::addSuccess('machine-removed', $machineuuid);
- } else {
- Message::addWarning('machine-not-runmode', $machineuuid);
- }
+ } else {
+ $deleted = 0;
+ }
+ Message::addSuccess('runmode.enabled-removed-save', $active, $deleted);
+ Util::redirect('?do=runmode&module=' . $module . '&modeid=' . $modeId, true);
+ }
+
+ private function handleDeleteMachine()
+ {
+ $machineuuid = Request::post('machineuuid', false, 'string');
+ if ($machineuuid === false) {
+ Message::addError('main.parameter-missing', 'machineuuid');
+ return;
+ }
+ $mode = RunMode::getRunMode($machineuuid, RunMode::DATA_MACHINE_DATA | RunMode::DATA_DETAILED);
+ if ($mode === false) {
+ Message::addError('runmode.machine-not-found', $machineuuid);
+ return;
+ }
+ $modConfig = RunMode::getModuleConfig($mode['module']);
+ if ($modConfig === false) {
+ Message::addError('module-hasnt-runmode', $mode['moduleName']);
+ return;
+ }
+ if (!$modConfig->allowGenericEditor || $modConfig->deleteUrlSnippet !== false) {
+ Message::addError('runmode.cannot-edit-module', $mode['moduleName']);
+ return;
+ }
+ if (!$modConfig->userHasPermission($mode['locationid'])) {
+ Message::addError('runmode.machine-no-permission', $machineuuid);
+ return;
+ }
+ if (RunMode::setRunMode($machineuuid, null, null)) {
+ Message::addSuccess('machine-removed', $machineuuid);
+ } else {
+ Message::addWarning('machine-not-runmode', $machineuuid);
}
}
@@ -107,7 +170,7 @@ class Page_RunMode extends Page
Message::addError('main.no-such-module', $moduleId);
Util::redirect('?do=runmode');
}
- $module->activate();
+ $module->activate(1, false);
$config = RunMode::getModuleConfig($moduleId);
if ($config === false) {
Message::addError('module-hasnt-runmode', $moduleId);
@@ -117,7 +180,13 @@ class Page_RunMode extends Page
$modeId = Request::get('modeid', false, 'string');
if ($modeId !== false) {
// Show edit page for specific module-mode combo
- $this->renderModuleMode($module, $modeId);
+ $this->renderModuleMode($module, $modeId, $config);
+ return;
+ }
+ // Permissions
+ if (!$config->userHasPermission(null) && !User::hasPermission('list-all')) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=runmode');
return;
}
// Show list of machines with assigned mode for this module
@@ -152,6 +221,16 @@ class Page_RunMode extends Page
$modules[$row['module']]['list'][] = $row;
}
foreach ($modules as $moduleId => $rows) {
+ if ($onlyModule === false) {
+ // Permissions - not required if rendering specific module, since it's been already done
+ if ($rows['config']->userHasPermission(null)) {
+ $disabled = '';
+ } elseif (User::hasPermission('list-all')) {
+ $disabled = 'disabled';
+ } else {
+ continue;
+ } // </Permissions>
+ }
$module = Module::get($moduleId);
if ($module === false)
continue;
@@ -161,7 +240,8 @@ class Page_RunMode extends Page
'modulename' => $module->getDisplayName(),
'module' => $moduleId,
'canedit' => $config !== false && $config->allowGenericEditor && $config->deleteUrlSnippet === false,
- 'deleteUrl' => $config->deleteUrlSnippet
+ 'deleteUrl' => $config->deleteUrlSnippet,
+ 'disabled' => $disabled,
));
}
}
@@ -169,8 +249,9 @@ class Page_RunMode extends Page
/**
* @param \Module $module
* @param string $modeId
+ * @param \RunModeModuleConfig $config
*/
- private function renderModuleMode($module, $modeId)
+ private function renderModuleMode($module, $modeId, $config)
{
$moduleId = $module->getIdentifier();
$modeName = RunMode::getModeName($moduleId, $modeId);
@@ -183,42 +264,81 @@ class Page_RunMode extends Page
Util::redirect($redirect);
}
if (!RunMode::getModuleConfig($moduleId)->allowGenericEditor) {
- Message::addError('runmode.cannot-edit-module', $module);
+ Message::addError('runmode.cannot-edit-module', $moduleId);
Util::redirect($redirect);
}
+ // Permissions
+ if ($config->userHasPermission(null)) {
+ $disabled = '';
+ } elseif (User::hasPermission('list-all')) {
+ $disabled = 'disabled';
+ } else {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=runmode');
+ return;
+ }
+ $machines = RunMode::getForMode($module, $modeId, true);
+ if ($config->permission !== false) {
+ $allowed = User::getAllowedLocations($config->permission);
+ $machines = array_values(array_filter($machines, function ($item) use ($allowed) {
+ return in_array($item['locationid'], $allowed);
+ }));
+ }
Render::addTemplate('machine-selector', [
'module' => $moduleId,
'modeid' => $modeId,
'moduleName' => $module->getDisplayName(),
'modeName' => $modeName,
- 'machines' => json_encode(RunMode::getForMode($module, $modeId, true)),
+ 'machines' => json_encode($machines),
'redirect' => $redirect,
+ 'disabled' => $disabled,
+ 'add-only' => $config->deleteUrlSnippet !== false,
]);
}
protected function doAjax()
{
$action = Request::any('action', false, 'string');
+ if ($action !== 'getmachines')
+ return;
+ $query = Request::get('query', false, 'string');
+ if (strlen($query) < 2)
+ return;
- if ($action === 'getmachines') {
- $query = Request::get('query', false, 'string');
-
- $result = Database::simpleQuery('SELECT m.machineuuid, m.macaddr, m.clientip, m.hostname, m.locationid, '
- . 'r.module, r.modeid '
- . 'FROM machine m '
- . 'LEFT JOIN runmode r USING (machineuuid) '
- . 'WHERE machineuuid LIKE :query '
- . ' OR macaddr LIKE :query '
- . ' OR clientip LIKE :query '
- . ' OR hostname LIKE :query '
- . ' LIMIT 100', ['query' => "%$query%"]);
+ User::load();
+ $config = RunMode::getModuleConfig(Request::any('module', '', 'string'));
+ $returnObject = ['machines' => []];
- $returnObject = [
- 'machines' => $result->fetchAll(PDO::FETCH_ASSOC)
- ];
+ if ($config !== false) {
+ $params = ['query' => "%$query%"];
+ if ($config->permission === false) {
+ // Global
+ $condition = '1';
+ } else {
+ $params['locations'] = User::getAllowedLocations($config->permission);
+ $condition = 'locationid IN (:locations)';
+ if (in_array(0, $params['locations'])) {
+ $condition .= ' OR locationid IS NULL';
+ }
+ }
+ if ($config->permission === false || !empty($params['locations'])) {
+ $result = Database::simpleQuery("SELECT m.machineuuid, m.macaddr, m.clientip, m.hostname, m.locationid,
+ r.module, r.modeid
+ FROM machine m
+ LEFT JOIN runmode r USING (machineuuid)
+ WHERE ($condition) AND (machineuuid LIKE :query
+ OR macaddr LIKE :query
+ OR clientip LIKE :query
+ OR hostname LIKE :query)
+ LIMIT 100", $params);
- echo json_encode($returnObject);
+ $returnObject = [
+ 'machines' => $result->fetchAll(PDO::FETCH_ASSOC)
+ ];
+ }
}
+ echo json_encode($returnObject);
+
}
} \ No newline at end of file
diff --git a/modules-available/runmode/permissions/permissions.json b/modules-available/runmode/permissions/permissions.json
new file mode 100644
index 00000000..53dfdab0
--- /dev/null
+++ b/modules-available/runmode/permissions/permissions.json
@@ -0,0 +1,5 @@
+{
+ "list-all": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/runmode/templates/machine-selector.html b/modules-available/runmode/templates/machine-selector.html
index 7f37f5a2..665c56f3 100644
--- a/modules-available/runmode/templates/machine-selector.html
+++ b/modules-available/runmode/templates/machine-selector.html
@@ -1,12 +1,7 @@
<h1>{{lang_assignRunmodeToMachine}}</h1>
<h2>{{moduleName}} // {{modeName}}</h2>
-<p>{{lang_assignMachineIntroText}}</p>
-<div class="hidden">
- {{#machines}}
- <div id="qex-{{machineuuid}}">{{hostname}}</div>
- {{/machines}}
-</div>
+<p>{{lang_assignMachineIntroText}}</p>
<h4>{{lang_addNewMachines}}</h4>
<form method="post" action="?do=runmode">
@@ -15,13 +10,19 @@
<input type="hidden" name="module" value="{{module}}" id="i-module">
<input type="hidden" name="modeid" value="{{modeid}}" id="i-modeid">
<input type="hidden" name="redirect" value="{{redirect}}">
- <select id="machine-sel" name="machines[]" multiple>
+ <select id="machine-sel" name="machines[]" multiple {{disabled}}>
</select>
<div class="buttonbar">
- <button type="submit" class="btn btn-primary">{{lang_save}}</button>
+ <button type="button" class="btn btn-default" onClick="javascript:history.back()">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-primary" {{disabled}}>{{lang_save}}</button>
</div>
</form>
+{{#add-only}}
+ <h4>{{lang_existingClients}}</h4>
+ <div id="existing-list"></div>
+{{/add-only}}
+
<script type="application/javascript"><!--
const MODULE = document.getElementById('i-module').value;
@@ -58,7 +59,7 @@ function loadMachines(query, callback) {
}
}
$.ajax({
- url: '?do=runmode&action=getmachines&query=' + encodeURIComponent(query),
+ url: '?do=runmode&action=getmachines&module={{module}}&query=' + encodeURIComponent(query),
type: 'GET',
dataType: 'json',
error: function () {
@@ -120,6 +121,17 @@ document.addEventListener('DOMContentLoaded', function () {
})();
});
var old = {{{machines}}} || [];
+ var list = $('#existing-list');
+ if (list.length !== 0) {
+ old.forEach(function (x) { list.append(renderMachineOption(x, function(str) {
+ return (str + '')
+ .replace(/&/g, '&amp;')
+ .replace(/</g, '&lt;')
+ .replace(/>/g, '&gt;')
+ .replace(/"/g, '&quot;');
+ }))});
+ old = [];
+ }
var $box = $('#machine-sel').selectize({
options: old,
items: old.map(function(x) { return x.machineuuid; }),
@@ -132,7 +144,7 @@ document.addEventListener('DOMContentLoaded', function () {
load: loadMachines,
maxItems: null,
sortField: 'hostname',
- sortDirection: 'asc',
+ sortDirection: 'asc'
});
});
diff --git a/modules-available/runmode/templates/module-machine-list.html b/modules-available/runmode/templates/module-machine-list.html
index 283fb393..89424922 100644
--- a/modules-available/runmode/templates/module-machine-list.html
+++ b/modules-available/runmode/templates/module-machine-list.html
@@ -36,12 +36,12 @@
</td>
<td class="text-center">
{{#canedit}}
- <button type="submit" class="btn btn-danger btn-sm" name="machineuuid" value="{{machineuuid}}">
+ <button type="submit" class="btn btn-danger btn-sm" name="machineuuid" value="{{machineuuid}}" {{disabled}}>
<span class="glyphicon glyphicon-trash"></span>
</button>
{{/canedit}}
{{#deleteUrl}}
- <a class="btn btn-default btn-sm" href="?do={{module}}&amp;{{deleteUrl}}{{modeid}}">
+ <a class="btn btn-default btn-sm {{disabled}}" href="?do={{module}}&amp;{{deleteUrl}}{{modeid}}">
<span class="glyphicon glyphicon-edit"></span>
</a>
{{/deleteUrl}}
diff --git a/modules-available/serversetup-bwlp-ipxe/api.inc.php b/modules-available/serversetup-bwlp-ipxe/api.inc.php
new file mode 100644
index 00000000..73461901
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/api.inc.php
@@ -0,0 +1,252 @@
+<?php
+
+// Menu mode
+
+$serverIp = Property::getServerIp();
+
+// Check if required arguments are given; if not, spit out according script and chain to self
+$uuid = Request::any('uuid', false, 'string');
+// Get platform - EFI or PCBIOS
+$platform = Request::any('platform', false, 'string');
+$manuf = Request::any('manuf', false, 'string');
+$product = Request::any('product', false, 'string');
+$slxExtensions = Request::any('slx-extensions', false, 'int');
+
+if ($platform === false || ($uuid === false && $product === false) || $slxExtensions === false) {
+ // Redirect to self with added parameters
+ $url = parse_url($_SERVER['REQUEST_URI']);
+ if (isset($_SERVER['SCRIPT_URI']) && preg_match('#^(\w+://[^/]+)#', $_SERVER['SCRIPT_URI'], $out)) {
+ $urlbase = $out[1];
+ } elseif (isset($_SERVER['REQUEST_SCHEME']) && isset($_SERVER['SERVER_NAME'])) {
+ $urlbase = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'];
+ } elseif (isset($_SERVER['REQUEST_SCHEME']) && isset($_SERVER['SERVER_ADDR'])) {
+ $urlbase = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_ADDR'];
+ } else {
+ $urlbase = 'http://' . $serverIp;
+ }
+ $urlbase .= $url['path'];
+ if (empty($url['query'])) {
+ $arr = [];
+ } else {
+ parse_str($url['query'], $arr);
+ foreach ($arr as &$v) {
+ $v = urlencode($v);
+ }
+ unset($v);
+ }
+ $arr['uuid'] = '${uuid}';
+ $arr['mac'] = '${mac}';
+ $arr['manuf'] = '${manufacturer:uristring}';
+ $arr['product'] = '${product:uristring}';
+ $arr['platform'] = '${platform:uristring}';
+ $query = '?';
+ foreach ($arr as $k => $v) {
+ $query .= $k . '=' . $v . '&';
+ }
+ //$query = substr($query, 0, -1);
+ echo <<<HERE
+#!ipxe
+set slxtest:string something ||
+iseq \${slxtest:md5} \${} && set slxext 0 || set slxext 1 ||
+clear slxtest ||
+set self {$urlbase}{$query}slx-extensions=\${slxext}
+:retry
+echo Chaining to \${self}
+chain -ar \${self} ||
+echo Chaining to self failed with \${errno}, retrying in a bit...
+sleep 5
+goto retry
+HERE;
+ exit;
+}
+// ipxe has it lowercase, but we use uppercase
+$platform = strtoupper($platform);
+
+$BOOT_METHODS = Localboot::BOOT_METHODS;
+
+$ip = $_SERVER['REMOTE_ADDR'];
+if (substr($ip, 0, 7) === '::ffff:') {
+ $ip = substr($ip, 7);
+}
+$menu = IPxeMenu::forClient($ip, $uuid);
+
+
+// Get preferred localboot method, depending on system model
+$localboot = false;
+$model = false;
+if ($uuid !== false && Module::get('statistics') !== false) {
+ // If we have the machine table, we rather try to look up the system model from there, using the UUID
+ $row = Database::queryFirst('SELECT systemmodel FROM machine WHERE machineuuid = :uuid', ['uuid' => $uuid]);
+ if ($row !== false && !empty($row['systemmodel'])) {
+ $model = $row['systemmodel'];
+ }
+}
+if ($model === false) {
+ // Otherwise use what iPXE sent us
+ function modfilt($str)
+ {
+ if (empty($str) || preg_match('/product\s+name|be\s+filled|unknown|default\s+string/i', $str))
+ return false;
+ return trim(preg_replace('/\s+/', ' ', $str));
+ }
+ $manuf = modfilt($manuf);
+ $product = modfilt($product);
+ if (!empty($product)) {
+ $model = $product;
+ if (!empty($manuf)) {
+ $model .= " ($manuf)";
+ }
+ }
+}
+// Query
+if ($model !== false) {
+ $row = Database::queryFirst("SELECT bootmethod FROM serversetup_localboot WHERE systemmodel = :model LIMIT 1",
+ ['model' => $model]);
+ if ($row !== false) {
+ $localboot = $row['bootmethod'];
+ }
+}
+if ($localboot === false || !isset($BOOT_METHODS[$localboot])) {
+ $localboot = Property::get(Localboot::PROPERTY_KEY, 'AUTO');
+ if (!isset($BOOT_METHODS[$localboot])) {
+ $localboot = 'AUTO';
+ }
+}
+if (isset($BOOT_METHODS[$localboot])) {
+ // Move preferred method first
+ $BOOT_METHODS[] = $BOOT_METHODS[$localboot];
+ unset($BOOT_METHODS[$localboot]);
+ $BOOT_METHODS = array_reverse($BOOT_METHODS);
+}
+
+if ($slxExtensions) {
+ $slxConsoleUpdate = '--update';
+} else {
+ $slxConsoleUpdate = '';
+}
+
+$output = <<<HERE
+#!ipxe
+
+goto init || goto fail ||
+
+# functions
+
+# password check with gotos
+# set slx_hash to the expected hash
+# slx_salt to the salt to use
+# slx_pw_ok to the label to jump on success
+# slx_pw_fail to label for wrong pw
+:slx_pass_check
+login ||
+set slxtmp_pw \${password:md5}-\${slx_salt} || goto fail
+set slxtmp_pw \${slxtmp_pw:md5} || goto fail
+clear password ||
+iseq \${slxtmp_pw} \${slx_hash} || prompt Wrong password. Press a key. ||
+iseq \${slxtmp_pw} \${slx_hash} || goto \${slx_pw_fail} ||
+iseq \${slxtmp_pw} \${slx_hash} && goto \${slx_pw_ok} ||
+goto fail
+
+# local boot with either exit 1 or sanboot
+:slx_localboot
+console ||
+
+HERE;
+
+foreach ($BOOT_METHODS as $line) {
+ $output .= "$line || goto fail\n";
+}
+
+$output .= <<<HERE
+goto fail
+
+# start
+:init
+
+set ipappend1 ip=\${ip}:{$serverIp}:\${gateway}:\${netmask}
+set ipappend2 BOOTIF=01-\${mac:hexhyp}
+set serverip $serverIp ||
+
+# Clean up in case we've been chained to
+imgfree ||
+
+imgfetch --name bg-menu /tftp/pxe-menu.png ||
+
+:start
+
+console --left 55 --top 88 --right 63 --bottom 64 --keep --picture bg-menu ||
+
+colour --rgb 0xffffff 7
+colour --rgb 0xcccccc 5
+cpair --foreground 0 --background 4 1
+cpair --foreground 7 --background 5 2
+cpair --foreground 7 --background 9 0
+
+:slx_menu
+
+console --left 55 --top 88 --right 63 --bottom 64 $slxConsoleUpdate --keep --picture bg-menu ||
+
+HERE;
+
+$output .= $menu->getMenuDefinition('target', $platform, $slxExtensions);
+
+$output .= <<<HERE
+
+console --left 60 --top 130 --right 67 --bottom 86 $slxConsoleUpdate ||
+goto \${target} ||
+echo Could not find menu entry in script.
+prompt Press any key to continue.
+goto start
+
+HERE;
+
+$output .= $menu->getItemsCode($platform);
+
+/*
+
+:i5
+chain -a /tftp/memtest.0 passes=1 onepass || goto membad
+prompt Memory OK. Press a key.
+goto init
+
+:i8
+set x:int32 0
+:again
+console --left 60 --top 130 --right 67 --bottom 96 --picture bg-load --keep ||
+console --left 55 --top 88 --right 63 --bottom 64 --picture bg-menu --keep ||
+inc x
+iseq \${x} 20 || goto again
+prompt DONE. Press dein Knie.
+goto slx_menu
+
+:membad
+iseq \${errno} 0x1 || goto memaborted
+params
+param scrot \${vram}
+imgfetch -a http://132.230.8.113/screen.php##params ||
+prompt Memory is bad. Press a key.
+goto init
+
+:memaborted
+params
+param scrot \${vram}
+imgfetch -a http://132.230.8.113/screen.php##params ||
+prompt Memory test aborted. Press a key.
+goto init
+
+*/
+
+$output .= <<<HERE
+:fail
+prompt Boot failed. Press any key to start.
+goto init
+HERE;
+
+if ($platform === 'EFI') {
+ $cs = 'ASCII';
+} else {
+ $cs = 'IBM437';
+}
+Header('Content-Type: text/plain; charset=' . $cs);
+
+echo iconv('UTF-8', $cs . '//TRANSLIT//IGNORE', $output);
diff --git a/modules-available/serversetup-bwlp-ipxe/config.json b/modules-available/serversetup-bwlp-ipxe/config.json
new file mode 100644
index 00000000..8b3ce2a3
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/config.json
@@ -0,0 +1,8 @@
+{
+ "category": "main.settings-server",
+ "dependencies" : [
+ "locations",
+ "js_jqueryui",
+ "bootstrap_multiselect"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/hooks/bootup.inc.php b/modules-available/serversetup-bwlp-ipxe/hooks/bootup.inc.php
new file mode 100644
index 00000000..50ac04ae
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/hooks/bootup.inc.php
@@ -0,0 +1,11 @@
+<?php
+
+$ret = IPxe::importLegacyMenu(false);
+if ($ret !== false) {
+ $num = IPxe::importPxeMenus('/srv/openslx/tftp/pxelinux.cfg');
+ if ($num > 0) {
+ EventLog::info('Imported old PXELinux menu, with ' . $num . ' additional IP-range based menus.');
+ } else {
+ EventLog::info('Imported old PXELinux menu.');
+ }
+}
diff --git a/modules-available/serversetup-bwlp-ipxe/hooks/ipxe-update.inc.php b/modules-available/serversetup-bwlp-ipxe/hooks/ipxe-update.inc.php
new file mode 100644
index 00000000..583c5a2b
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/hooks/ipxe-update.inc.php
@@ -0,0 +1,10 @@
+<?php
+
+$data = [
+ 'ipaddress' => Property::getServerIp()
+];
+$task = Taskmanager::submit('CompileIPxeNew', $data);
+if (!isset($task['id']))
+ return false;
+Property::set('ipxe-task-id', $task['id'], 15);
+return $task['id']; \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/hooks/main-warning.inc.php b/modules-available/serversetup-bwlp-ipxe/hooks/main-warning.inc.php
index a2eba6ff..a2eba6ff 100644
--- a/modules-available/serversetup-bwlp/hooks/main-warning.inc.php
+++ b/modules-available/serversetup-bwlp-ipxe/hooks/main-warning.inc.php
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
new file mode 100644
index 00000000..69adffd3
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php
@@ -0,0 +1,258 @@
+<?php
+
+abstract class BootEntry
+{
+
+ public function __construct($data = false)
+ {
+ if (is_array($data)) {
+ foreach ($data as $key => $value) {
+ if (property_exists($this, $key)) {
+ $this->{$key} = $value;
+ }
+ }
+ }
+ }
+
+ public abstract function supportsMode($mode);
+
+ public abstract function toScript($failLabel, $mode);
+
+ public abstract function toArray();
+
+ public abstract function addFormFields(&$array);
+
+ /*
+ *
+ */
+
+ /**
+ * Return a BootEntry instance from the serialized data.
+ *
+ * @param string $jsonString serialized entry data
+ * @return BootEntry|null instance representing boot entry, null on error
+ */
+ public static function fromJson($data)
+ {
+ if (is_string($data)) {
+ $data = json_decode($data, true);
+ }
+ if (isset($data['script'])) {
+ return new CustomBootEntry($data);
+ }
+ if (isset($data['executable'])) {
+ return new StandardBootEntry($data);
+ }
+ return null;
+ }
+
+ public static function newStandardBootEntry($initData)
+ {
+ $ret = new StandardBootEntry($initData);
+ $list = [];
+ if ($ret->arch() !== StandardBootEntry::EFI) {
+ $list[] = StandardBootEntry::BIOS;
+ }
+ if ($ret->arch() === StandardBootEntry::EFI || $ret->arch() === StandardBootEntry::BOTH) {
+ $list[] = StandardBootEntry::EFI;
+ }
+ foreach ($list as $mode) {
+ if (empty($initData['executable'][$mode]))
+ return null;
+ }
+ return $ret;
+ }
+
+ public static function newCustomBootEntry($initData)
+ {
+ if (empty($initData['script']))
+ return null;
+ return new CustomBootEntry($initData);
+ }
+
+ /**
+ * Return a BootEntry instance from database with the given id.
+ *
+ * @param string $id
+ * @return BootEntry|null|false false == unknown id, null = unknown entry type, BootEntry instance on success
+ */
+ public static function fromDatabaseId($id)
+ {
+ $row = Database::queryFirst("SELECT data FROM serversetup_bootentry
+ WHERE entryid = :id LIMIT 1", ['id' => $id]);
+ if ($row === false)
+ return false;
+ return self::fromJson($row['data']);
+ }
+
+}
+
+class StandardBootEntry extends BootEntry
+{
+ protected $executable;
+ protected $initRd;
+ protected $commandLine;
+ protected $replace;
+ protected $autoUnload;
+ protected $resetConsole;
+ protected $arch; // Constants below
+
+ const BIOS = 'PCBIOS'; // Only valid for legacy BIOS boot
+ const EFI = 'EFI'; // Only valid for EFI boot
+ const BOTH = 'PCBIOS-EFI'; // Supports both via distinct entry
+ const AGNOSTIC = 'agnostic'; // Supports both via same entry (PCBIOS entry)
+
+ public function __construct($data = false)
+ {
+ if ($data instanceof PxeSection) {
+ // Gets arrayfied below
+ $this->executable = $data->kernel;
+ $this->initRd = $data->initrd;
+ $this->commandLine = ' ' . str_replace('vga=current', '', $data->append) . ' ';
+ $this->resetConsole = true;
+ $this->replace = true;
+ $this->autoUnload = true;
+ if (strpos($this->commandLine, ' quiet ') !== false) {
+ $this->commandLine .= ' loglevel=5 rd.systemd.show_status=auto';
+ }
+ if ($data->ipAppend & 1) {
+ $this->commandLine .= ' ${ipappend1}';
+ }
+ if ($data->ipAppend & 2) {
+ $this->commandLine .= ' ${ipappend2}';
+ }
+ if ($data->ipAppend & 4) {
+ $this->commandLine .= ' SYSUUID=${uuid}';
+ }
+ $this->commandLine = trim(preg_replace('/\s+/', ' ', $this->commandLine));
+ } else {
+ parent::__construct($data);
+ }
+ // Convert legacy DB format
+ foreach (['executable', 'initRd', 'commandLine', 'replace', 'autoUnload', 'resetConsole'] as $key) {
+ if (!is_array($this->{$key})) {
+ $this->{$key} = [ 'PCBIOS' => $this->{$key}, 'EFI' => '' ];
+ }
+ }
+ if ($this->arch === null) {
+ $this->arch = self::AGNOSTIC;
+ }
+ }
+
+ public function arch()
+ {
+ return $this->arch;
+ }
+
+ public function supportsMode($mode)
+ {
+ if ($mode === $this->arch || $this->arch === self::AGNOSTIC)
+ return true;
+ if ($mode === self::BIOS || $mode === self::EFI) {
+ return $this->arch === self::BOTH;
+ }
+ error_log('Unknown iPXE platform: ' . $mode);
+ return false;
+ }
+
+ public function toScript($failLabel, $mode)
+ {
+ if (!$this->supportsMode($mode)) {
+ return "prompt Entry doesn't have an executable for mode $mode\n";
+ }
+ if ($this->arch === self::AGNOSTIC) {
+ $mode = self::BIOS;
+ }
+
+ $script = '';
+ if ($this->resetConsole[$mode]) {
+ $script .= "console ||\n";
+ }
+ if (!empty($this->initRd[$mode])) {
+ $script .= "imgfree ||\n";
+ if (!is_array($this->initRd[$mode])) {
+ $script .= "initrd {$this->initRd[$mode]} || goto $failLabel\n";
+ } else {
+ foreach ($this->initRd[$mode] as $initrd) {
+ $script .= "initrd $initrd || goto $failLabel\n";
+ }
+ }
+ }
+ $script .= "boot ";
+ if ($this->autoUnload[$mode]) {
+ $script .= "-a ";
+ }
+ if ($this->replace[$mode]) {
+ $script .= "-r ";
+ }
+ $script .= $this->executable[$mode];
+ $rdBase = basename($this->initRd[$mode]);
+ if (!empty($this->commandLine[$mode])) {
+ $script .= " initrd=$rdBase {$this->commandLine[$mode]}";
+ }
+ $script .= " || goto $failLabel\n";
+ if ($this->resetConsole[$mode]) {
+ $script .= "goto start ||\n";
+ }
+ return $script;
+ }
+
+ public function addFormFields(&$array)
+ {
+ $array[$this->arch . '_selected'] = 'selected';
+ foreach ([self::BIOS, self::EFI] as $mode) {
+ $array['entries'][] = [
+ 'is' . $mode => true,
+ 'mode' => $mode,
+ 'executable' => $this->executable[$mode],
+ 'initRd' => $this->initRd[$mode],
+ 'commandLine' => $this->commandLine[$mode],
+ 'replace_checked' => $this->replace[$mode] ? 'checked' : '',
+ 'autoUnload_checked' => $this->autoUnload[$mode] ? 'checked' : '',
+ 'resetConsole_checked' => $this->resetConsole[$mode] ? 'checked' : '',
+ ];
+ }
+ $array['exec_checked'] = 'checked';
+ }
+
+ public function toArray()
+ {
+ return [
+ 'executable' => $this->executable,
+ 'initRd' => $this->initRd,
+ 'commandLine' => $this->commandLine,
+ 'replace' => $this->replace,
+ 'autoUnload' => $this->autoUnload,
+ 'resetConsole' => $this->resetConsole,
+ 'arch' => $this->arch,
+ ];
+ }
+}
+
+class CustomBootEntry extends BootEntry
+{
+ protected $script;
+
+ public function supportsMode($mode)
+ {
+ return true;
+ }
+
+ public function toScript($failLabel, $mode)
+ {
+ return str_replace('%fail%', $failLabel, $this->script) . "\n";
+ }
+
+ public function addFormFields(&$array)
+ {
+ $array['entry'] = [
+ 'script' => $this->script,
+ ];
+ $array['script_checked'] = 'checked';
+ }
+
+ public function toArray()
+ {
+ return ['script' => $this->script];
+ }
+}
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php
new file mode 100644
index 00000000..d34839f0
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php
@@ -0,0 +1,453 @@
+<?php
+
+class IPxe
+{
+
+ /**
+ * Import all IP-Range based pxe menus from the given directory.
+ *
+ * @param string $configPath The pxelinux.cfg path where to look for menu files in hexadecimal IP format.
+ * @return Number of menus imported
+ */
+ public static function importPxeMenus($configPath)
+ {
+ $importCount = 0;
+ $menus = [];
+ foreach (glob($configPath . '/*', GLOB_NOSORT) as $file) {
+ if (!is_file($file) || !preg_match('~/[A-F0-9]{1,8}$~', $file))
+ continue;
+ $content = file_get_contents($file);
+ if ($content === false)
+ continue;
+ $file = basename($file);
+ $start = hexdec(str_pad($file,8, '0'));
+ $end = hexdec(str_pad($file,8, 'f')); // TODO ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^PREFIX
+ error_log('From ' . long2ip($start) . ' to ' . long2ip($end));
+ $res = Database::simpleQuery("SELECT locationid, startaddr, endaddr FROM subnet
+ WHERE startaddr >= :start AND endaddr <= :end", compact('start', 'end'));
+ $locations = [];
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($locations as &$loc) {
+ if ($row['startaddr'] <= $loc['startaddr'] && $row['endaddr'] >= $loc['endaddr']) {
+ $loc = false;
+ } elseif ($row['startaddr'] >= $loc['startaddr'] && $row['endaddr'] <= $loc['endaddr']) {
+ continue 2;
+ }
+ }
+ unset($loc);
+ $locations[] = $row;
+ }
+ $menu = PxeLinux::parsePxeLinux($content);
+ $key = $menu->hash(true);
+ if (isset($menus[$key])) {
+ $menuId = $menus[$key];
+ $defId = null;
+ // Figure out the default label, get it's label name
+ foreach ($menu->sections as $section) {
+ if ($section->isDefault) {
+ $defId = $section;
+ } elseif ($defId === null && $section->label === $menu->timeoutLabel) {
+ $defId = $section;
+ }
+ }
+ if ($defId !== null) {
+ $defId = self::cleanLabelFixLocal($defId);
+ // Confirm it actually exists (it should since the menu seems identical) and get menuEntryId
+ $me = Database::queryFirst('SELECT m.defaultentryid, me.menuentryid FROM serversetup_bootentry be
+ INNER JOIN serversetup_menuentry me ON (be.entryid = me.entryid)
+ INNER JOIN serversetup_menu m ON (m.menuid = me.menuid)
+ WHERE be.entryid = :id AND me.menuid = :menuid',
+ ['id' => $defId, 'menuid' => $menuId]);
+ if ($me === false || $me['defaultentryid'] == $me['menuentryid']) {
+ $defId = null; // Not found, or is already default - don't override if it's the same
+ } else {
+ $defId = $me['menuentryid'];
+ }
+ }
+ } else {
+ $menuId = self::insertMenu($menu, 'Imported', false, 0, [], []);
+ $menus[$key] = $menuId;
+ $defId = null;
+ $importCount++;
+ }
+ if ($menuId === false)
+ continue;
+ foreach ($locations as $loc) {
+ if ($loc === false)
+ continue;
+ Database::exec('INSERT IGNORE INTO serversetup_menu_location (menuid, locationid, defaultentryid)
+ VALUES (:menuid, :locationid, :def)', [
+ 'menuid' => $menuId,
+ 'locationid' => $loc['locationid'],
+ 'def' => $defId,
+ ]);
+ }
+ }
+ return $importCount;
+ }
+
+ public static function importLegacyMenu($force = false)
+ {
+ if (!$force && false !== Database::queryFirst("SELECT entryid FROM serversetup_bootentry WHERE entryid = 'bwlp-default'"))
+ return false; // Already exists
+ // Now create the default entry
+ self::createDefaultEntries();
+ $prepend = ['bwlp-default' => false, 'localboot' => false];
+ $defaultLabel = 'bwlp-default';
+ $menuTitle = 'bwLehrpool Bootauswahl';
+ $pxeConfig = '';
+ $timeoutSecs = 60;
+ // Try to import any customization
+ $oldMenu = Property::getBootMenu();
+ if (is_array($oldMenu)) {
+ //
+ if (isset($oldMenu['timeout'])) {
+ $timeoutSecs = (int)$oldMenu['timeout'];
+ }
+ if (isset($oldMenu['defaultentry'])) {
+ if ($oldMenu['defaultentry'] === 'net') {
+ $defaultLabel = 'bwlp-default';
+ } elseif ($oldMenu['defaultentry'] === 'hdd') {
+ $defaultLabel = 'localboot';
+ } elseif ($oldMenu['defaultentry'] === 'custom') {
+ $defaultLabel = 'custom';
+ }
+ }
+ if (!empty($oldMenu['custom'])) {
+ $pxeConfig = $oldMenu['custom'];
+ }
+ }
+ $append = [
+ '',
+ 'bwlp-default-dbg' => false,
+ '',
+ 'poweroff' => false,
+ ];
+ return self::insertMenu(PxeLinux::parsePxeLinux($pxeConfig), $menuTitle, $defaultLabel, $timeoutSecs, $prepend, $append);
+ }
+
+ /**
+ * @param PxeMenu $pxeMenu
+ * @param string $menuTitle
+ * @param string|false $defaultLabel
+ * @param $defaultTimeoutSeconds
+ * @param $prepend
+ * @param $append
+ * @return bool|int
+ */
+ private static function insertMenu($pxeMenu, $menuTitle, $defaultLabel, $defaultTimeoutSeconds, $prepend, $append)
+ {
+ $timeoutMs = [];
+ $menuEntries = $prepend;
+ settype($menuEntries, 'array');
+ if (!empty($pxeMenu)) {
+ $pxe =& $pxeMenu;
+ if (!empty($pxe->title)) {
+ $menuTitle = $pxe->title;
+ }
+ if ($pxe->timeoutLabel !== null) {
+ $defaultLabel = $pxe->timeoutLabel;
+ }
+ $timeoutMs[] = $pxe->timeoutMs;
+ $timeoutMs[] = $pxe->totalTimeoutMs;
+ foreach ($pxe->sections as $section) {
+ if ($section->localBoot || preg_match('/chain\.c32$/i', $section->kernel)) {
+ $menuEntries['localboot'] = 'localboot';
+ continue;
+ }
+ if ($section->label === null) {
+ if (!$section->isHidden && !empty($section->title)) {
+ $menuEntries[] = $section->title;
+ }
+ continue;
+ }
+ if (empty($section->kernel)) {
+ if (!$section->isHidden && !empty($section->title)) {
+ $menuEntries[] = $section->title;
+ }
+ continue;
+ }
+ $entry = self::pxe2BootEntry($section);
+ if ($entry === null)
+ continue;
+ $label = self::cleanLabelFixLocal($section);
+ if ($defaultLabel === $section->label) {
+ $defaultLabel = $label;
+ }
+ $hotkey = MenuEntry::filterKeyName($section->hotkey);
+ // Create boot entry
+ $data = $entry->toArray();
+ Database::exec('INSERT IGNORE INTO serversetup_bootentry (entryid, hotkey, title, builtin, data)
+ VALUES (:label, :hotkey, :title, 0, :data)', [
+ 'label' => $label,
+ 'hotkey' => $hotkey,
+ 'title' => self::sanitizeIpxeString($section->title),
+ 'data' => json_encode($data),
+ ]);
+ $menuEntries[$label] = $section;
+ }
+ }
+ if (is_array($append)) {
+ $menuEntries += $append;
+ }
+ if (empty($menuEntries))
+ return false;
+ // Make menu
+ $timeoutMs = array_filter($timeoutMs, 'is_int');
+ if (empty($timeoutMs)) {
+ $timeoutMs = (int)($defaultTimeoutSeconds * 1000);
+ } else {
+ $timeoutMs = min($timeoutMs);
+ }
+ $isDefault = (int)(Database::queryFirst('SELECT menuid FROM serversetup_menu WHERE isdefault = 1') === false);
+ Database::exec("INSERT INTO serversetup_menu (timeoutms, title, defaultentryid, isdefault)
+ VALUES (:timeoutms, :title, NULL, :isdefault)", [
+ 'title' => self::sanitizeIpxeString($menuTitle),
+ 'timeoutms' => $timeoutMs,
+ 'isdefault' => $isDefault,
+ ]);
+ $menuId = Database::lastInsertId();
+ if (!array_key_exists($defaultLabel, $menuEntries) && $timeoutMs > 0) {
+ $defaultLabel = array_keys($menuEntries)[0];
+ }
+ // Link boot entries to menu
+ $defaultEntryId = null;
+ $order = 1000;
+ foreach ($menuEntries as $label => $entry) {
+ if (is_string($entry)) {
+ // Gap entry
+ Database::exec("INSERT INTO serversetup_menuentry
+ (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass)
+ VALUES (:menuid, :entryid, :hotkey, :title, :hidden, :sortval, '', '')", [
+ 'menuid' => $menuId,
+ 'entryid' => null,
+ 'hotkey' => '',
+ 'title' => self::sanitizeIpxeString($entry),
+ 'hidden' => 0,
+ 'sortval' => $order += 100,
+ ]);
+ continue;
+ }
+ $data = Database::queryFirst("SELECT entryid, hotkey, title FROM serversetup_bootentry WHERE entryid = :entryid", ['entryid' => $label]);
+ if ($data === false)
+ continue;
+ $data['pass'] = '';
+ $data['hidden'] = 0;
+ if ($entry instanceof PxeSection) {
+ $data['hidden'] = (int)$entry->isHidden;
+ // Prefer explicit data from this imported menu over the defaults
+ $data['title'] = self::sanitizeIpxeString($entry->title);
+ if (MenuEntry::getKeyCode($entry->hotkey) !== false) {
+ $data['hotkey'] = $entry->hotkey;
+ }
+ if (!empty($entry->passwd)) {
+ // Most likely it's a hash so we cannot recover; ask people to reset
+ $data['pass'] ='please_reset';
+ }
+ }
+ $data['menuid'] = $menuId;
+ $data['sortval'] = $order += 100;
+ $res = Database::exec("INSERT INTO serversetup_menuentry
+ (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass)
+ VALUES (:menuid, :entryid, :hotkey, :title, :hidden, :sortval, :pass, :pass)", $data);
+ if ($res !== false && $label === $defaultLabel) {
+ $defaultEntryId = Database::lastInsertId();
+ }
+ }
+ // Now we can set default entry
+ if (!empty($defaultEntryId)) {
+ Database::exec("UPDATE serversetup_menu SET defaultentryid = :entryid WHERE menuid = :menuid",
+ ['menuid' => $menuId, 'entryid' => $defaultEntryId]);
+ }
+ // TODO: masterpw? rather pointless....
+ //$oldMenu['masterpasswordclear'];
+ return $menuId;
+ }
+
+ private static function createDefaultEntries()
+ {
+ $query = 'INSERT IGNORE INTO serversetup_bootentry (entryid, hotkey, title, builtin, data)
+ VALUES (:entryid, :hotkey, :title, 1, :data)';
+ Database::exec($query,
+ [
+ 'entryid' => 'bwlp-default',
+ 'hotkey' => 'B',
+ 'title' => 'bwLehrpool-Umgebung starten',
+ 'data' => json_encode([
+ 'executable' => '/boot/default/kernel',
+ 'initRd' => '/boot/default/initramfs-stage31',
+ 'commandLine' => 'slxbase=boot/default quiet splash loglevel=5 rd.systemd.show_status=auto intel_iommu=igfx_off ${ipappend1} ${ipappend2}',
+ 'replace' => true,
+ 'autoUnload' => true,
+ 'resetConsole' => true,
+ ]),
+ ]);
+ Database::exec($query,
+ [
+ 'entryid' => 'bwlp-default-dbg',
+ 'hotkey' => '',
+ 'title' => 'bwLehrpool-Umgebung starten (nosplash, debug)',
+ 'data' => json_encode([
+ 'executable' => '/boot/default/kernel',
+ 'initRd' => '/boot/default/initramfs-stage31',
+ 'commandLine' => 'slxbase=boot/default loglevel=7 intel_iommu=igfx_off ${ipappend1} ${ipappend2}',
+ 'replace' => true,
+ 'autoUnload' => true,
+ 'resetConsole' => true,
+ ]),
+ ]);
+ Database::exec($query,
+ [
+ 'entryid' => 'localboot',
+ 'hotkey' => 'L',
+ 'title' => 'Lokales System starten',
+ 'data' => json_encode([
+ 'script' => 'goto slx_localboot || goto %fail% ||',
+ ]),
+ ]);
+ Database::exec($query,
+ [
+ 'entryid' => 'poweroff',
+ 'hotkey' => 'P',
+ 'title' => 'Power off',
+ 'data' => json_encode([
+ 'script' => 'poweroff || goto %fail% ||',
+ ]),
+ ]);
+ Database::exec($query,
+ [
+ 'entryid' => 'reboot',
+ 'hotkey' => 'R',
+ 'title' => 'Reboot',
+ 'data' => json_encode([
+ 'script' => 'reboot || goto %fail% ||',
+ ]),
+ ]);
+ }
+
+ /**
+ * Create unique label for a boot entry. It will try to figure out whether
+ * this is one of our default entries and if not, create a unique label
+ * representing the menu entry contents.
+ * Also it patches the entry if it's referencing the local bwlp install
+ * because side effects.
+ *
+ * @param PxeSection $section
+ * @return string
+ */
+ private static function cleanLabelFixLocal($section)
+ {
+ $myip = Property::getServerIp();
+ // Detect our "old" entry types
+ if (count($section->initrd) === 1 && preg_match(",$myip/boot/default/kernel\$,", $section->kernel)
+ && preg_match(",$myip/boot/default/initramfs-stage31\$,", $section->initrd[0])) {
+ // Kernel and initrd match, examine KCL
+ if ($section->append === 'slxbase=boot/default vga=current quiet splash') {
+ // Normal
+ return 'bwlp-default';
+ } elseif ($section->append === 'slxbase=boot/default') {
+ // Debug output
+ return 'bwlp-default-dbg';
+ } else {
+ // Transform to relative URL, leave KCL, fall through to generic label gen
+ $section->kernel = '/boot/default/kernel';
+ $section->initrd = ['/boot/default/initramfs-stage31'];
+ }
+ }
+ // Generic -- "smart" hash of kernel, initrd and command line
+ $str = $section->kernel . ' ' . implode(',', $section->initrd);
+ $array = preg_split('/\s+/', $section->append, -1, PREG_SPLIT_NO_EMPTY);
+ sort($array);
+ $str .= ' ' . implode(' ', $array);
+
+ return 'i-' . substr(md5($str), 0, 12);
+ }
+
+ /**
+ * @param PxeSection $section
+ * @return BootEntry|null The according boot entry, null if it's unparsable
+ */
+ private static function pxe2BootEntry($section)
+ {
+ if (preg_match('/(pxechain\.com|pxechn\.c32)$/i', $section->kernel)) {
+ // Chaining -- create script
+ $args = preg_split('/\s+/', $section->append);
+ $script = '';
+ $file = false;
+ for ($i = 0; $i < count($args); ++$i) {
+ $arg = $args[$i];
+ if ($arg === '-c') { // PXELINUX config file option
+ ++$i;
+ $script .= "set 209:string {$args[$i]} || goto %fail%\n";
+ } elseif ($arg === '-p') { // PXELINUX prefix path option
+ ++$i;
+ $script .= "set 210:string {$args[$i]} || goto %fail%\n";
+ } elseif ($arg === '-t') { // PXELINUX timeout option
+ ++$i;
+ $script .= "set 211:int32 {$args[$i]} || goto %fail%\n";
+ } elseif ($arg === '-o') { // Overriding various DHCP options
+ ++$i;
+ if (preg_match('/^((?:0x)?[a-f0-9]{1,4})\.([bwlsh])=(.*)$/i', $args[$i], $out)) {
+ // TODO: 'q' (8byte) unsupported for now
+ $opt = intval($out[1], 0);
+ if ($opt > 0 && $opt < 255) {
+ static $optType = ['b' => 'uint8', 'w' => 'uint16', 'l' => 'int32', 's' => 'string', 'h' => 'hex'];
+ $type = $optType[$out[2]];
+ $script .= "set {$opt}:{$type} {$args[$i]} || goto %fail%\n";
+ }
+ }
+ } elseif ($arg{0} === '-') {
+ continue;
+ } elseif ($file === false) {
+ $file = self::parseFile($arg);
+ }
+ }
+ if ($file !== false) {
+ $url = parse_url($file);
+ if (isset($url['host'])) {
+ $script .= "set next-server {$url['host']} || goto %fail%\n";
+ }
+ if (isset($url['path'])) {
+ $script .= "set filename {$url['path']} || goto %fail%\n";
+ }
+ $script .= "chain -ar {$file} || goto %fail%\n";
+ return new CustomBootEntry(['script' => $script]);
+ }
+ return null;
+ }
+ // "Normal" entry that should be convertible into a StandardBootEntry
+ $section->kernel = self::parseFile($section->kernel);
+ foreach ($section->initrd as &$initrd) {
+ $initrd = self::parseFile($initrd);
+ }
+ return BootEntry::newStandardBootEntry($section);
+ }
+
+ /**
+ * Parse PXELINUX file notion. Basically, turn
+ * server::file into tftp://server/file.
+ *
+ * @param string $file
+ * @return string
+ */
+ private static function parseFile($file)
+ {
+ if (preg_match(',^([^:/]+)::(.*)$,', $file, $out)) {
+ return 'tftp://' . $out[1] . '/' . $out[2];
+ }
+ return $file;
+ }
+
+ public static function sanitizeIpxeString($string)
+ {
+ return str_replace(['&', '|', ';', '$', "\r", "\n"], ['+', '/', ':', 'S', ' ', ' '], $string);
+ }
+
+ public static function makeMd5Pass($plainpass, $salt)
+ {
+ if (empty($plainpass))
+ return '';
+ return md5(md5($plainpass) . '-' . $salt);
+ }
+
+}
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
new file mode 100644
index 00000000..5c1a87d5
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxemenu.inc.php
@@ -0,0 +1,142 @@
+<?php
+
+class IPxeMenu
+{
+
+ protected $menuid;
+ protected $timeoutMs;
+ protected $title;
+ protected $defaultEntryId;
+ /**
+ * @var MenuEntry[]
+ */
+ protected $items = [];
+
+ public function __construct($menu)
+ {
+ if (!is_array($menu)) {
+ $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid FROM serversetup_menu
+ WHERE menuid = :menuid LIMIT 1", ['menuid' => $menu]);
+ if (!is_array($menu)) {
+ $menu = ['menuid' => 'foo', 'title' => 'Invalid Menu ID: ' . (int)$menu];
+ }
+ }
+ $this->menuid = (int)$menu['menuid'];
+ $this->timeoutMs = (int)$menu['timeoutms'];
+ $this->title = $menu['title'];
+ $this->defaultEntryId = $menu['defaultentryid'];
+ $res = Database::simpleQuery("SELECT e.menuentryid, e.entryid, e.hotkey, e.title, e.hidden, e.sortval, e.md5pass,
+ b.data AS bootentry
+ FROM serversetup_menuentry e
+ LEFT JOIN serversetup_bootentry b USING (entryid)
+ WHERE e.menuid = :menuid
+ ORDER BY e.sortval ASC, e.title ASC", ['menuid' => $menu['menuid']]);
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $this->items[] = new MenuEntry($row);
+ }
+ }
+
+ public function getMenuDefinition($targetVar, $mode, $slxExtensions)
+ {
+ $str = "menu -- {$this->title}\n";
+ foreach ($this->items as $item) {
+ $str .= $item->getMenuItemScript("m_{$this->menuid}", $this->defaultEntryId, $mode, $slxExtensions);
+ }
+ if ($this->defaultEntryId === null) {
+ $defaultLabel = "mx_{$this->menuid}_poweroff";
+ } else {
+ $defaultLabel = "m_{$this->menuid}_{$this->defaultEntryId}";
+ }
+ $str .= "choose";
+ if ($this->timeoutMs > 0) {
+ $str .= " --timeout {$this->timeoutMs}";
+ }
+ $str .= " $targetVar || goto $defaultLabel || goto fail\n";
+ if ($this->defaultEntryId === null) {
+ $str .= "goto skip_{$defaultLabel}\n"
+ . ":{$defaultLabel}\n"
+ . "poweroff || goto fail\n"
+ . ":skip_{$defaultLabel}\n";
+ }
+ return $str;
+ }
+
+ public function getItemsCode($mode)
+ {
+ $str = '';
+ foreach ($this->items as $item) {
+ $str .= $item->getBootEntryScript("m_{$this->menuid}", 'fail', $mode);
+ $str .= "goto slx_menu\n";
+ }
+ return $str;
+ }
+
+ /*
+ *
+ */
+
+ public static function forLocation($locationId)
+ {
+ $chain = null;
+ if (Module::isAvailable('location')) {
+ $chain = Location::getLocationRootChain($locationId);
+ }
+ if (!empty($chain)) {
+ $res = Database::simpleQuery("SELECT m.menuid, m.timeoutms, m.title, IFNULL(ml.defaultentryid, m.defaultentryid) AS defaultentryid, ml.locationid
+ FROM serversetup_menu m
+ INNER JOIN serversetup_menu_location ml USING (menuid)
+ WHERE ml.locationid IN (:chain)", ['chain' => $chain]);
+ if ($res->rowCount() > 0) {
+ // Make the location id key, preserving order (closest location is first)
+ $chain = array_flip($chain);
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ // Overwrite the value (numeric ascending values, useless) with menu array of according location
+ $chain[(int)$row['locationid']] = $row;
+ }
+ // Use first one that was found
+ foreach ($chain as $menu) {
+ if (is_array($menu)) {
+ return new IPxeMenu($menu);
+ }
+ }
+ // Should never end up here, but we'd just fall through and use the default
+ }
+ }
+ // We're here, no specific menu, use default
+ $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid
+ FROM serversetup_menu
+ ORDER BY isdefault DESC LIMIT 1");
+ if ($menu === false) {
+ return new EmptyIPxeMenu;
+ }
+ return new IPxeMenu($menu);
+ }
+
+ public static function forClient($ip, $uuid)
+ {
+ $locationId = 0;
+ if (Module::isAvailable('location')) {
+ $locationId = Location::getFromIpAndUuid($ip, $uuid);
+ }
+ return self::forLocation($locationId);
+ }
+
+}
+
+class EmptyIPxeMenu extends IPxeMenu
+{
+
+ /** @noinspection PhpMissingParentConstructorInspection */
+ public function __construct()
+ {
+ $this->title = 'No menu defined';
+ $this->menuid = -1;
+ $this->items[] = new MenuEntry([
+ 'title' => 'Please create a menu in Server-Setup first'
+ ]);
+ $this->items[] = new MenuEntry([
+ 'title' => 'Bitte erstellen Sie zunächst ein Menü'
+ ]);
+ }
+
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/localboot.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/localboot.inc.php
new file mode 100644
index 00000000..3ab81862
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/inc/localboot.inc.php
@@ -0,0 +1,15 @@
+<?php
+
+class Localboot
+{
+
+ const PROPERTY_KEY = 'serversetup.localboot';
+
+ const BOOT_METHODS = [
+ 'AUTO' => 'iseq efi ${platform} && exit 1 || sanboot --no-describe',
+ 'EXIT' => 'exit 1',
+ 'COMBOOT' => 'chain /tftp/chain.c32 hd0',
+ 'SANBOOT' => 'sanboot --no-describe',
+ ];
+
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php
new file mode 100644
index 00000000..d243fd23
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/inc/menuentry.inc.php
@@ -0,0 +1,177 @@
+<?php
+
+class MenuEntry
+{
+ /**
+ * @var int id of entry, used for pw
+ */
+ private $menuentryid;
+ /**
+ * @var false|string key code as expected by iPXE
+ */
+ private $hotkey;
+ /**
+ * @var string
+ */
+ private $title;
+ /**
+ * @var bool
+ */
+ private $hidden;
+ /**
+ * @var bool
+ */
+ private $gap;
+ /**
+ * @var int
+ */
+ private $sortval;
+ /**
+ * @var BootEntry
+ */
+ private $bootEntry = null;
+
+ private $md5pass = null;
+
+ /**
+ * MenuEntry constructor.
+ *
+ * @param array $row row from database
+ */
+ public function __construct($row)
+ {
+ if (is_array($row)) {
+ foreach ($row as $key => $value) {
+ if (property_exists($this, $key)) {
+ $this->{$key} = $value;
+ }
+ }
+ $this->hotkey = self::getKeyCode($row['hotkey']);
+ if (!empty($row['bootentry'])) {
+ $this->bootEntry = BootEntry::fromJson($row['bootentry']);
+ }
+ $this->gap = (array_key_exists('entryid', $row) && $row['entryid'] === null);
+ }
+ settype($this->hidden, 'bool');
+ settype($this->gap, 'bool');
+ settype($this->sortval, 'int');
+ settype($this->menuentryid, 'int');
+ }
+
+ public function getMenuItemScript($lblPrefix, $requestedDefaultId, $mode, $slxExtensions)
+ {
+ if ($this->bootEntry !== null && !$this->bootEntry->supportsMode($mode))
+ return '';
+ $str = 'item ';
+ if ($this->gap) {
+ $str .= '--gap ';
+ } else {
+ if ($this->hidden && $slxExtensions) {
+ if ($this->hotkey === false)
+ return ''; // Hidden entries without hotkey are illegal
+ $str .= '--hidden ';
+ }
+ if ($this->hotkey !== false) {
+ $str .= '--key ' . $this->hotkey . ' ';
+ }
+ if ($this->menuentryid == $requestedDefaultId) {
+ $str .= '--default ';
+ }
+ $str .= "{$lblPrefix}_{$this->menuentryid} ";
+ }
+ if (empty($this->title)) {
+ $str .= '${}';
+ } else {
+ $str .= $this->title;
+ }
+ return $str . " || prompt Could not create menu item for {$lblPrefix}_{$this->menuentryid}\n";
+ }
+
+ public function getBootEntryScript($lblPrefix, $failLabel, $mode)
+ {
+ if ($this->bootEntry === null || !$this->bootEntry->supportsMode($mode))
+ return '';
+ $str = ":{$lblPrefix}_{$this->menuentryid}\n";
+ if (!empty($this->md5pass)) {
+ $str .= "set slx_hash {$this->md5pass} || goto $failLabel\n"
+ . "set slx_salt {$this->menuentryid} || goto $failLabel\n"
+ . "set slx_pw_ok {$lblPrefix}_ok || goto $failLabel\n"
+ . "set slx_pw_fail slx_menu || goto $failLabel\n"
+ . "goto slx_pass_check || goto $failLabel\n"
+ . ":{$lblPrefix}_ok\n";
+ }
+ return $str . $this->bootEntry->toScript($failLabel, $mode);
+ }
+
+ /*
+ *
+ */
+
+ private static function getKeyArray()
+ {
+ static $data = false;
+ if ($data === false) {
+ $data = [
+ 'F5' => 0x107e,
+ 'F6' => 0x127e,
+ 'F7' => 0x137e,
+ 'F8' => 0x147e,
+ 'F9' => 0x157e,
+ 'F10' => 0x167e,
+ 'F11' => 0x187e,
+ 'F12' => 0x197e,
+ ];
+ for ($i = 1; $i <= 26; ++$i) {
+ $letter = chr(0x40 + $i);
+ $data['SHIFT_' . $letter] = 0x40 + $i;
+ if ($letter !== 'C') {
+ $data['CTRL_' . $letter] = $i;
+ }
+ $data[$letter] = 0x60 + $i;
+ }
+ for ($i = 0; $i <= 9; ++$i) {
+ $data[chr(0x30 + $i)] = 0x30 + $i;
+ }
+ asort($data, SORT_NUMERIC);
+ }
+ return $data;
+ }
+
+ /**
+ * Get all the known/supported keys, usable for menu items.
+ *
+ * @return string[] list of known key names
+ */
+ public static function getKeyList()
+ {
+ return array_keys(self::getKeyArray());
+ }
+
+ /**
+ * Get the key code ipxe expects for the given named
+ * key. Returns false if the key name is unknown.
+ *
+ * @param string $keyName
+ * @return false|string Key code as hex string, or false if not found
+ */
+ public static function getKeyCode($keyName)
+ {
+ $data = self::getKeyArray();
+ if (isset($data[$keyName]))
+ return '0x' . dechex($data[$keyName]);
+ return false;
+ }
+
+ /**
+ * @param string $keyName desired key name
+ * @return string $keyName if it's known, empty string otherwise
+ */
+ public static function filterKeyName($keyName)
+ {
+ $data = self::getKeyArray();
+ if (isset($data[$keyName]))
+ return $keyName;
+ return '';
+ }
+
+}
diff --git a/modules-available/serversetup-bwlp-ipxe/inc/pxelinux.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/pxelinux.inc.php
new file mode 100644
index 00000000..1d022fef
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/inc/pxelinux.inc.php
@@ -0,0 +1,302 @@
+<?php
+
+
+class PxeLinux
+{
+
+ /**
+ * Takes a (partial) pxelinux menu and parses it into
+ * a PxeMenu object.
+ * @param string $input The pxelinux menu to parse
+ * @return PxeMenu the parsed menu
+ */
+ public static function parsePxeLinux($input)
+ {
+ /*
+ LABEL openslx-debug
+ MENU LABEL ^bwLehrpool-Umgebung starten (nosplash, debug)
+ KERNEL http://IPADDR/boot/default/kernel
+ INITRD http://IPADDR/boot/default/initramfs-stage31
+ APPEND slxbase=boot/default
+ IPAPPEND 3
+ */
+ $menu = new PxeMenu;
+ $sectionPropMap = [
+ 'menu label' => ['string', 'title'],
+ 'menu default' => ['true', 'isDefault'],
+ 'menu hide' => ['true', 'isHidden'],
+ 'menu disabled' => ['true', 'isDisabled'],
+ 'menu indent' => ['int', 'indent'],
+ 'kernel' => ['string', 'kernel'],
+ 'com32' => ['string', 'kernel'],
+ 'pxe' => ['string', 'kernel'],
+ 'initrd' => ['string', 'initrd'],
+ 'append' => ['string', 'append'],
+ 'ipappend' => ['int', 'ipAppend'],
+ 'sysappend' => ['int', 'ipAppend'],
+ 'localboot' => ['int', 'localBoot'],
+ ];
+ $globalPropMap = [
+ 'timeout' => ['int', 'timeoutMs', 100],
+ 'totaltimeout' => ['int', 'totalTimeoutMs', 100],
+ 'menu title' => ['string', 'title'],
+ 'menu clear' => ['true', 'menuClear'],
+ 'menu immediate' => ['true', 'immediateHotkeys'],
+ 'ontimeout' => ['string', 'timeoutLabel'],
+ ];
+ $lines = preg_split('/[\r\n]+/', $input);
+ $section = null;
+ $count = count($lines);
+ for ($li = 0; $li < $count; ++$li) {
+ $line =& $lines[$li];
+ if (!preg_match('/^\s*([^m]\S*|menu\s+\S+)(\s+.*?|)\s*$/i', $line, $out))
+ continue;
+ $val = trim($out[2]);
+ $key = trim($out[1]);
+ $key = strtolower($key);
+ $key = preg_replace('/\s+/', ' ', $key);
+ if ($key === 'label') {
+ if ($section !== null) {
+ $menu->sections[] = $section;
+ }
+ $section = new PxeSection($val);
+ } elseif ($key === 'menu separator') {
+ if ($section !== null) {
+ $menu->sections[] = $section;
+ $section = null;
+ }
+ $menu->sections[] = new PxeSection(null);
+ } elseif (self::handleKeyword($key, $val, $globalPropMap, $menu)) {
+ continue;
+ } elseif ($section === null) {
+ continue;
+ } elseif ($key === 'text' && strtolower($val) === 'help') {
+ $text = '';
+ while (++$li < $count) {
+ $line =& $lines[$li];
+ if (strtolower(trim($line)) === 'endtext')
+ break;
+ $text .= $line . "\n";
+ }
+ $section->helpText = $text;
+ } elseif (self::handleKeyword($key, $val, $sectionPropMap, $section)) {
+ continue;
+ }
+ }
+ if ($section !== null) {
+ $menu->sections[] = $section;
+ }
+ foreach ($menu->sections as $section) {
+ $section->mangle();
+ }
+ return $menu;
+ }
+
+ /**
+ * Check if keyword is valid and if so, add its interpreted value
+ * to the given object. The map to look up the keyword has to be passed
+ * as well as the object to set the value in. Map and object should
+ * obviously match.
+ * @param string $key keyword of parsed line
+ * @param string $val raw value of currently parsed line (empty if not present)
+ * @param array $map Map in which $key is looked up as key
+ * @param PxeMenu|PxeSection The object to set the parsed and sanitized value in
+ * @return bool true if the value was found in the map (and set in the object), false otherwise
+ */
+ private static function handleKeyword($key, $val, $map, $object)
+ {
+ if (!isset($map[$key]))
+ return false;
+ $opt = $map[$key];
+ // opt[0] is the type the value should be cast to; special case "true" means
+ // this is a bool option that will be set as soon as the keyword is present,
+ // as it doesn't have any parameters
+ if ($opt[0] === 'true') {
+ $val = true;
+ } else {
+ settype($val, $opt[0]);
+ }
+ // If opt[2] is present it's a multiplier for the value
+ if (isset($opt[2])) {
+ $val *= $opt[2];
+ }
+ $object->{$opt[1]} = $val;
+ return true;
+ }
+
+}
+
+/**
+ * Class representing a parsed pxelinux menu. Members
+ * will be set to their annotated type if present or
+ * be null otherwise, except for present-only boolean
+ * options, which will default to false.
+ */
+class PxeMenu
+{
+
+ /**
+ * @var string menu title, shown at the top of the menu
+ */
+ public $title;
+ /**
+ * @var int initial timeout after which $timeoutLabel would be executed
+ */
+ public $timeoutMs;
+ /**
+ * @var int if the user canceled the timeout by pressing a key, this timeout would still eventually
+ * trigger and launch the $timeoutLabel section
+ */
+ public $totalTimeoutMs;
+ /**
+ * @var string label of section which will execute if the timeout expires
+ */
+ public $timeoutLabel;
+ /**
+ * @var bool hide menu and just show background after triggering an entry
+ */
+ public $menuClear = false;
+ /**
+ * @var bool boot the associated entry directly if its corresponding hotkey is pressed instead of just highlighting
+ */
+ public $immediateHotkeys = false;
+ /**
+ * @var PxeSection[] list of sections the menu contains
+ */
+ public $sections = [];
+
+ public function hash($fuzzy)
+ {
+ $ctx = hash_init('md5');
+ if (!$fuzzy) {
+ hash_update($ctx, $this->title);
+ hash_update($ctx, $this->timeoutLabel);
+ }
+ hash_update($ctx, $this->timeoutMs);
+ foreach ($this->sections as $section) {
+ if ($fuzzy) {
+ hash_update($ctx, mb_strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $section->title)));
+ } else {
+ hash_update($ctx, $section->label);
+ hash_update($ctx, $section->title);
+ hash_update($ctx, $section->indent);
+ hash_update($ctx, $section->helpText);
+ hash_update($ctx, $section->isDefault);
+ hash_update($ctx, $section->hotkey);
+ }
+ hash_update($ctx, $section->kernel);
+ hash_update($ctx, $section->append);
+ hash_update($ctx, $section->ipAppend);
+ hash_update($ctx, $section->passwd);
+ hash_update($ctx, $section->isHidden);
+ hash_update($ctx, $section->isDisabled);
+ hash_update($ctx, $section->localBoot);
+ foreach ($section->initrd as $initrd) {
+ hash_update($ctx, $initrd);
+ }
+ }
+ return hash_final($ctx, false);
+ }
+
+}
+
+/**
+ * Class representing a parsed pxelinux menu entry. Members
+ * will be set to their annotated type if present or
+ * be null otherwise, except for present-only boolean
+ * options, which will default to false.
+ */
+class PxeSection
+{
+
+ /**
+ * @var string label used internally in PXEMENU definition to address this entry
+ */
+ public $label;
+ /**
+ * @var string MENU LABEL of PXEMENU - title of entry displayed to the user
+ */
+ public $title;
+ /**
+ * @var int Number of spaces to prefix the title with
+ */
+ public $indent;
+ /**
+ * @var string help text to display when the entry is highlighted
+ */
+ public $helpText;
+ /**
+ * @var string Kernel to load
+ */
+ public $kernel;
+ /**
+ * @var string|string[] initrd to load for the kernel.
+ * If mangle() has been called this will be an array,
+ * otherwise it's a comma separated list.
+ */
+ public $initrd;
+ /**
+ * @var string command line options to pass to the kernel
+ */
+ public $append;
+ /**
+ * @var int IPAPPEND from PXEMENU. Bitmask of valid options 1 and 2.
+ */
+ public $ipAppend;
+ /**
+ * @var string Password protecting the entry. This is most likely in crypted form.
+ */
+ public $passwd;
+ /**
+ * @var bool whether this section is marked as default (booted after timeout)
+ */
+ public $isDefault = false;
+ /**
+ * @var bool Menu entry is not visible (can only be triggered by timeout)
+ */
+ public $isHidden = false;
+ /**
+ * @var bool Disable this entry, making it unselectable
+ */
+ public $isDisabled = false;
+ /**
+ * @var int Value of the LOCALBOOT field
+ */
+ public $localBoot;
+ /**
+ * @var string hotkey to trigger item. Only valid after calling mangle()
+ */
+ public $hotkey;
+
+ public function __construct($label) { $this->label = $label; }
+
+ public function mangle()
+ {
+ if (($i = strpos($this->title, '^')) !== false) {
+ $this->hotkey = strtoupper($this->title{$i+1});
+ $this->title = substr($this->title, 0, $i) . substr($this->title, $i + 1);
+ }
+ if (strpos($this->append, 'initrd=') !== false) {
+ $parts = preg_split('/\s+/', $this->append);
+ $this->append = '';
+ for ($i = 0; $i < count($parts); ++$i) {
+ if (preg_match('/^initrd=(.*)$/', $parts[$i], $out)) {
+ if (!empty($this->initrd)) {
+ $this->initrd .= ',';
+ }
+ $this->initrd .= $out[1];
+ } else {
+ $this->append .= ' ' . $parts[$i];
+ }
+ }
+ $this->append = trim($this->append);
+ }
+ if (is_string($this->initrd)) {
+ $this->initrd = explode(',', $this->initrd);
+ } elseif (!is_array($this->initrd)) {
+ $this->initrd = [];
+ }
+ }
+
+}
+
diff --git a/modules-available/serversetup-bwlp-ipxe/install.inc.php b/modules-available/serversetup-bwlp-ipxe/install.inc.php
new file mode 100644
index 00000000..25579c13
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/install.inc.php
@@ -0,0 +1,89 @@
+<?php
+
+$res = array();
+
+$res[] = tableCreate('serversetup_bootentry', "
+ `entryid` varchar(16) CHARACTER SET ascii NOT NULL,
+ `hotkey` varchar(8) CHARACTER SET ascii NOT NULL,
+ `title` varchar(100) NOT NULL,
+ `builtin` tinyint(1) NOT NULL,
+ `data` blob NOT NULL,
+ PRIMARY KEY (`entryid`)
+");
+
+$res[] = tableCreate('serversetup_menu', "
+ `menuid` int(11) NOT NULL AUTO_INCREMENT,
+ `timeoutms` int(10) unsigned NOT NULL,
+ `title` varchar(100) NOT NULL COMMENT 'Escaped/Sanitized for iPXE!',
+ `defaultentryid` int(11) DEFAULT NULL,
+ `isdefault` tinyint(1) NOT NULL,
+ PRIMARY KEY (`menuid`),
+ KEY `defaultentryid` (`defaultentryid`),
+ KEY `isdefault` (`isdefault`)
+");
+
+$res[] = tableCreate('serversetup_menuentry', "
+ `menuentryid` int(11) NOT NULL AUTO_INCREMENT,
+ `menuid` int(11) NOT NULL,
+ `entryid` varchar(16) CHARACTER SET ascii NULL COMMENT 'If NULL, entry is gap',
+ `hotkey` varchar(8) CHARACTER SET ascii NOT NULL,
+ `title` varchar(100) NOT NULL COMMENT 'Sanitize this before insert',
+ `hidden` tinyint(1) NOT NULL,
+ `sortval` int(11) NOT NULL,
+ `plainpass` varchar(80) NOT NULL,
+ `md5pass` char(32) CHARACTER SET ascii NOT NULL,
+ PRIMARY KEY (`menuentryid`),
+ KEY `menuid` (`menuid`,`entryid`),
+ KEY `entryid` (`entryid`)
+");
+
+$res[] = tableCreate('serversetup_menu_location', '
+ `menuid` int(11) NOT NULL,
+ `locationid` int(11) NOT NULL,
+ `defaultentryid` int(11) DEFAULT NULL,
+ PRIMARY KEY (`menuid`,`locationid`),
+ UNIQUE `locationid` (`locationid`),
+ KEY `defaultentryid` (`defaultentryid`)
+');
+
+$res[] = tableCreate('serversetup_localboot', "
+ `systemmodel` varchar(120) NOT NULL,
+ `bootmethod` enum('EXIT','COMBOOT','SANBOOT') CHARACTER SET ascii NOT NULL,
+ PRIMARY KEY (`systemmodel`)
+");
+
+// Add defaultentry override column
+if (!tableHasColumn('serversetup_menu_location', 'defaultentryid')) {
+ if (Database::exec('ALTER TABLE serversetup_menu_location ADD COLUMN `defaultentryid` int(11) DEFAULT NULL,
+ ADD KEY `defaultentryid` (`defaultentryid`)') !== false) {
+ $res[] = UPDATE_DONE;
+ } else {
+ $res[] = UPDATE_FAILED;
+ }
+}
+
+$res[] = tableAddConstraint('serversetup_menu', 'defaultentryid', 'serversetup_menuentry', 'menuentryid',
+ 'ON DELETE SET NULL');
+
+$res[] = tableAddConstraint('serversetup_menuentry', 'entryid', 'serversetup_bootentry', 'entryid',
+ 'ON UPDATE CASCADE ON DELETE CASCADE');
+
+$res[] = tableAddConstraint('serversetup_menuentry', 'menuid', 'serversetup_menu', 'menuid',
+ 'ON UPDATE CASCADE ON DELETE CASCADE');
+
+$res[] = tableAddConstraint('serversetup_menu_location', 'menuid', 'serversetup_menu', 'menuid',
+ 'ON UPDATE CASCADE ON DELETE CASCADE');
+
+$res[] = tableAddConstraint('serversetup_menu_location', 'defaultentryid', 'serversetup_menuentry', 'menuentryid',
+ 'ON UPDATE CASCADE ON DELETE SET NULL');
+
+if (Module::get('location') !== false) {
+ if (!tableExists('location')) {
+ $res[] = UPDATE_RETRY;
+ } else {
+ $res[] = tableAddConstraint('serversetup_menu_location', 'locationid', 'location', 'locationid',
+ 'ON UPDATE CASCADE ON DELETE CASCADE');
+ }
+}
+
+responseFromArray($res);
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/de/messages.json b/modules-available/serversetup-bwlp-ipxe/lang/de/messages.json
new file mode 100644
index 00000000..8c5aab54
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/de/messages.json
@@ -0,0 +1,20 @@
+{
+ "boot-entry-created": "Men\u00fceintrag {{0}} erzeugt",
+ "boot-entry-updated": "Men\u00fceintrag {{0}} aktualisiert",
+ "bootentry-deleted": "Men\u00fceintrag gel\u00f6scht",
+ "error-saving-entry": "Fehler beim Speichern des Eintrags {{0}}: {{1}}",
+ "image-not-found": "USB-Image nicht gefunden. Generieren Sie das Bootmen\u00fc neu.",
+ "invalid-boot-entry": "Ung\u00fcltiger Men\u00fceintrag: {{0}}",
+ "invalid-ip": "Kein Interface ist auf die Adresse {{0}} konfiguriert",
+ "invalid-menu-id": "Ung\u00fcltige Men\u00fc-ID: {{0}}",
+ "localboot-invalid-method": "Ung\u00fcltige localboot-Methode: {{0}}",
+ "localboot-saved": "Einstellungen gespeichert",
+ "location-menu-assigned": "{{0}} wurde ein Men\u00fc zugewiesen",
+ "location-use-default": "{{0}} verwendet jetzt das Standardmen\u00fc",
+ "menu-deleted": "Men\u00fc gel\u00f6scht",
+ "menu-saved": "Men\u00fc wurde gespeichert",
+ "menu-set-default": "Standardmen\u00fc wurde gesetzt",
+ "missing-bootentry-data": "Fehlende Daten f\u00fcr den Men\u00fceintrag",
+ "no-ip-addr-set": "Bitte w\u00e4hlen Sie die prim\u00e4re IP-Adresse des Servers",
+ "unknown-bootentry-type": "Unbekannter Eintrags-Typ: {{0}}"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/de/module.json b/modules-available/serversetup-bwlp-ipxe/lang/de/module.json
new file mode 100644
index 00000000..9a8de39c
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/de/module.json
@@ -0,0 +1,19 @@
+{
+ "dl-efi": "UEFI",
+ "dl-hd": "HDD Partitions-Image",
+ "dl-i386": "32\u2009Bit",
+ "dl-lkrn": "In Kernel-Header gewrappt",
+ "dl-pcbios": "Legacy BIOS",
+ "dl-pcinic": "Mit PCI(e) Netzwerktreibern",
+ "dl-snp": "Verwendet SNP-Netzwerkschnittstelle",
+ "dl-usb": "USB-Image",
+ "dl-usbnic": "Mit USB Netzwerktreibern",
+ "dl-x86_64": "64\u2009Bit",
+ "module_name": "iPXE \/ Boot Menu",
+ "page_title": "PXE- und Boot-Einstellungen",
+ "submenu_address": "Server-Adresse",
+ "submenu_bootentry": "Men\u00fceintr\u00e4ge verwalten",
+ "submenu_download": "Downloads",
+ "submenu_localboot": "HDD-Boot",
+ "submenu_menu": "Men\u00fcs verwalten"
+}
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/de/permissions.json b/modules-available/serversetup-bwlp-ipxe/lang/de/permissions.json
new file mode 100644
index 00000000..9d7e77c6
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/de/permissions.json
@@ -0,0 +1,11 @@
+{
+ "access-page": "Seite sehen.",
+ "download": "USB-Image herunterladen.",
+ "edit.address": "Boot-Adresse des Servers ausw\u00e4hlen.",
+ "ipxe.bootentry.edit": "Einen Boot-Eintrag bearbeiten.",
+ "ipxe.bootentry.view": "Liste aller Boot-Eintr\u00e4ge sehen.",
+ "ipxe.localboot.edit": "Ausnahmeliste f\u00fcr Localboot-Modus bearbeiten.",
+ "ipxe.menu.assign": "Men\u00fc einem Raum\/Ort zuweisen.",
+ "ipxe.menu.edit": "Men\u00fc editieren.",
+ "ipxe.menu.view": "Liste der Men\u00fcs sehen."
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json b/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json
new file mode 100644
index 00000000..525b1562
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/de/template-tags.json
@@ -0,0 +1,75 @@
+{
+ "lang_active": "Aktiv",
+ "lang_add": "Hinzuf\u00fcgen",
+ "lang_addBootentry": "Men\u00fceintrag hinzuf\u00fcgen",
+ "lang_addMenu": "Men\u00fc hinzuf\u00fcgen",
+ "lang_additionalInfoLink": "Weitere Informationen",
+ "lang_archAgnostic": "Architekturunabh\u00e4ngig",
+ "lang_archBoth": "BIOS und EFI",
+ "lang_archSelector": "Architekturauswahl",
+ "lang_assignMenuToLocation": "Ort ein Men\u00fc zuweisen",
+ "lang_biosOnly": "Nur BIOS",
+ "lang_bootAddress": "Boot-Adresse des Servers",
+ "lang_bootEntryData": "Daten des Men\u00fceintrags",
+ "lang_bootentryDeleteConfirm": "Sind Sie sicher, dass Sie diesen Men\u00fceintrag l\u00f6schen wollen?",
+ "lang_bootentryHead": "Men\u00fceintr\u00e4ge",
+ "lang_bootentryIntro": "Hier k\u00f6nnen Sie Men\u00fceintr\u00e4ge definieren, die sich sp\u00e4ter einem Men\u00fc zuweisen lassen. Ein Men\u00fceintrag besteht entweder aus einem zu ladenen Kernel\/Image plus optional initrd, oder aus einem iPXE-Script.",
+ "lang_bootentryTitle": "Men\u00fceintrag",
+ "lang_chooseIP": "Bitte w\u00e4hlen Sie die IP-Adresse, \u00fcber die der Server von den Clients zum Booten angesprochen werden soll.",
+ "lang_commandLine": "Command line",
+ "lang_count": "Anzahl",
+ "lang_downloadBootImage": "Boot-Image herunterladen",
+ "lang_downloadRufus": "Rufus herunterladen",
+ "lang_editBuiltinWarn": "Achtung! Sie bearbeiten einen der vorgegebenen Eintr\u00e4ge! Bei einem Update k\u00f6nnten Ihre \u00c4nderungen wieder \u00fcberschrieben werden",
+ "lang_editMenuHead": "Men\u00fc bearbeiten",
+ "lang_efiOnly": "Nur EFI",
+ "lang_entryChooserTitle": "Men\u00fceintrag ausw\u00e4hlen",
+ "lang_entryId": "ID",
+ "lang_entryTitle": "Bezeichnung",
+ "lang_execAutoUnload": "Nach Ausf\u00fchrung entladen (--autofree)",
+ "lang_execReplace": "Aktuellen iPXE-Stack erstzen (--replace)",
+ "lang_execResetConsole": "Konsole vor Ausf\u00fchrung zur\u00fccksetzen",
+ "lang_forceRecompile": "Jetzt neu compilieren",
+ "lang_generationFailed": "Erzeugen des Bootmen\u00fcs fehlgeschlagen. Der Netzwerkboot von bwLehrpool wird wahrscheinlich nicht funktionieren. Wenn Sie den Fehler nicht selbst beheben k\u00f6nnen, melden Sie bitte die Logausgabe an das bwLehrpool-Projekt.",
+ "lang_hotkey": "Hotkey",
+ "lang_idFormatHint": "(Max. 16 Zeichen, nur a-z 0-9 - _)",
+ "lang_imageToLoad": "Zu ladendes Image (z.B. Kernel)",
+ "lang_initRd": "Zu ladendes initramfs",
+ "lang_ipxeWikiUrl": "im iPXE Wiki",
+ "lang_isDefault": "Standard",
+ "lang_listOfMenus": "Men\u00fcliste",
+ "lang_localBootDefault": "Standardm\u00e4\u00dfig verwendete Methode, um von Festplatte zu booten",
+ "lang_localBootExceptions": "Ausnahmen, pro Rechnermodell definierbar",
+ "lang_localBootHead": "Boot von Festplatte",
+ "lang_localBootIntro": "Aus dem iPXE Bootmen\u00fc kann auf verschiedene Arten ein Boot von der prim\u00e4ren Festplatte ausgel\u00f6st werden. In den allermeisten F\u00e4llen ist die Einstellung \"AUTO\" ausreichend, bei bestimmten Rechnermodellen kann es allerdings erforderlich sein, eine der alternativen Methoden zu erzwingen. Falls Sie einem solchen Modell begegnen, k\u00f6nnen Sie im unteren Teil dieser Seite eine solche Ausnahme festlegen. In einigen F\u00e4llen l\u00e4sst sich das Problem auch durch ein BIOS-Update auf den entsprechenden Ger\u00e4ten beheben.",
+ "lang_locationCount": "Anzahl Orte",
+ "lang_menuDeleteConfirm": "Sind Sie sicher, dass Sie dieses Men\u00fc l\u00f6schen wollen?",
+ "lang_menuEntryOverride": "Standardeintrag \u00fcberschreiben",
+ "lang_menuGeneration": "Erzeugen des Bootmen\u00fcs",
+ "lang_menuListIntro": "Hier sehen Sie eine Liste aller vorhandenen Men\u00fcs, deren Zuordnung zu R\u00e4umen sowie die M\u00f6glichkeit, diese zu editieren oder l\u00f6schen. Um ein Men\u00fc einem bestimmten Raum zuzuweisen, besuchen Sie bitte den Men\u00fcpunkt \"R\u00e4ume\/Orte\".",
+ "lang_menuTimeout": "Timeout",
+ "lang_menuTitle": "Men\u00fc",
+ "lang_moduleHeading": "iPXE \/ Boot Menu",
+ "lang_newBootEntryHead": "Neuer Men\u00fceintrag",
+ "lang_newMenu": "Neues Men\u00fc",
+ "lang_none": "(keine)",
+ "lang_override": "\u00dcberschreiben",
+ "lang_recompileHint": "iPXE-Binaries jetzt neu kompilieren. Normalerweise wird dieser Vorgang bei \u00c4nderungen automatisch ausgef\u00fchrt. Sollten Bootprobleme auftreten, k\u00f6nnen Sie hier den Vorgang manuell ansto\u00dfen.",
+ "lang_refCount": "Referenzen",
+ "lang_referencingMenus": "Verkn\u00fcpfte Men\u00fcs",
+ "lang_scriptContent": "Script",
+ "lang_seconds": "Sekunden",
+ "lang_set": "Setzen",
+ "lang_spacer": "Abstandhalter\/\u00dcberschrift",
+ "lang_systemmodel": "System-Modell",
+ "lang_title": "Titel",
+ "lang_typeExecEntry": "Standardeintrag",
+ "lang_typeScriptEntry": "Benutzerdefiniertes Script",
+ "lang_usbImage": "USB-Image",
+ "lang_usbImgHelp": "Mit dem USB-Image k\u00f6nnen Sie einen bootbaren USB-Stick erstellen, \u00fcber den sich bwLehrpool an Rechnern starten l\u00e4sst, die keinen Netzwerkboot unterst\u00fctzen, bzw. f\u00fcr die keine entsprechende DHCP-Konfiguration vorhanden ist. Dies erfordert dann lediglich, dass in der BIOS-Konfiguration des Rechners USB-Boot zugelassen ist. Der Stick dient dabei lediglich als Einstiegspunkt; es ist nach wie vor ein bwLehrpool-Satellitenserver f\u00fcr den eigentlichen Bootvorgang von N\u00f6ten.",
+ "lang_usbImgHelpBtn": "Bootbaren USB-Stick erstellen",
+ "lang_usbImgHelpLinux": "Nutzen Sie dd, um das Image auf einen USB-Stick zu schreiben. Das Image enth\u00e4lt bereits eine Partitionstabelle, achten Sie daher darauf, dass Sie das Image z.B. nach \/dev\/sdx schreiben, und nicht nach \/dev\/sdx1",
+ "lang_usbImgHelpWindows": "Unter Windows muss zun\u00e4chst ein Programm besorgt werden, mit dem sich Images direkt auf einen USB-Stick schreiben lassen. Es gibt gleich mehrere kostenlose und quelloffene Programme, eines davon ist Rufus. Rufus wurde mit dem bwLehrpool-Image gestetet. Nach dem Starten des Programms ist lediglich das heruntergeladene Image zu \u00f6ffnen, sowie in der Liste der Laufwerke der richtige USB-Stick auszuw\u00e4hlen (damit Sie nicht versehentlich Daten auf dem falschen Laufwerk \u00fcberschreiben!)",
+ "lang_useDefaultMenu": "\u00dcbergeordnetes Men\u00fc verwenden",
+ "lang_useDefaultMenuEntry": "(Vorgabe des Men\u00fcs)"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/en/messages.json b/modules-available/serversetup-bwlp-ipxe/lang/en/messages.json
new file mode 100644
index 00000000..dcdf4be1
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/en/messages.json
@@ -0,0 +1,20 @@
+{
+ "boot-entry-created": "Created menu item {{0}}",
+ "boot-entry-updated": "Updated menu item {{0}}",
+ "bootentry-deleted": "Deleted menu item",
+ "error-saving-entry": "Error saving item {{0}}: {{1}}",
+ "image-not-found": "USB image not found. Try regenerating the boot menu first.",
+ "invalid-boot-entry": "Invalid menu item: {{0}}",
+ "invalid-ip": "No interface is configured with the address {{0}}",
+ "invalid-menu-id": "Invalid menu id: {{0}}",
+ "localboot-invalid-method": "Invalid localboot method: {{0}}",
+ "localboot-saved": "Localboot settings have been saved",
+ "location-menu-assigned": "Assigned menu to {{0}}",
+ "location-use-default": "{{0}} is now using the inherited\/default menu",
+ "menu-deleted": "Menu deleted",
+ "menu-saved": "Menu saved",
+ "menu-set-default": "Default menu has been set",
+ "missing-bootentry-data": "Missing data for menu item",
+ "no-ip-addr-set": "Please set the server's primary IP address",
+ "unknown-bootentry-type": "Unknown item type: {{0}}"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/en/module.json b/modules-available/serversetup-bwlp-ipxe/lang/en/module.json
new file mode 100644
index 00000000..9e73e865
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/en/module.json
@@ -0,0 +1,19 @@
+{
+ "dl-efi": "UEFI",
+ "dl-hd": "HDD partition image",
+ "dl-i386": "32 bit",
+ "dl-lkrn": "wrapped in kernel header",
+ "dl-pcbios": "legacy BIOS",
+ "dl-pcinic": "with PCI(e) NIC drivers",
+ "dl-snp": "uses SNP\/NII interface",
+ "dl-usb": "thumb drive image",
+ "dl-usbnic": "with USB NIC drivers",
+ "dl-x86_64": "64 bit",
+ "module_name": "iPXE \/ Boot Menu",
+ "page_title": "iPXE and boot settings",
+ "submenu_address": "Server address",
+ "submenu_bootentry": "Manage menu items",
+ "submenu_download": "Downloads",
+ "submenu_localboot": "HDD boot",
+ "submenu_menu": "Manage menus"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/en/permissions.json b/modules-available/serversetup-bwlp-ipxe/lang/en/permissions.json
new file mode 100644
index 00000000..53ccec3a
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/en/permissions.json
@@ -0,0 +1,11 @@
+{
+ "access-page": "View page.",
+ "download": "Download USB Image.",
+ "edit.address": "Choose boot address of the server.",
+ "ipxe.bootentry.edit": "Edit menu items.",
+ "ipxe.bootentry.view": "View menu items.",
+ "ipxe.localboot.edit": "Edit local boot settings.",
+ "ipxe.menu.assign": "Assign menus to locations.",
+ "ipxe.menu.edit": "Edit menus.",
+ "ipxe.menu.view": "View menus."
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json b/modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json
new file mode 100644
index 00000000..ea57c522
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/lang/en/template-tags.json
@@ -0,0 +1,75 @@
+{
+ "lang_active": "Active",
+ "lang_add": "Add",
+ "lang_addBootentry": "Add Bootentry",
+ "lang_addMenu": "Add Menu",
+ "lang_additionalInfoLink": "Read more",
+ "lang_archAgnostic": "Architecture-agnostic",
+ "lang_archBoth": "BIOS and EFI",
+ "lang_archSelector": "Select architecture",
+ "lang_assignMenuToLocation": "Assign menu to location",
+ "lang_biosOnly": "BIOS only",
+ "lang_bootAddress": "Boot Address of the Server",
+ "lang_bootEntryData": "Menu entry data",
+ "lang_bootentryDeleteConfirm": "Are you sure you want to delete this menu item?",
+ "lang_bootentryHead": "Menu items",
+ "lang_bootentryIntro": "This is where you can add, edit and remove menu items, which can be added to menus. A menu entry is either a combination of a kernel\/image to load (and an optional initrd), or a custom iPXE-script.",
+ "lang_bootentryTitle": "Menu item",
+ "lang_chooseIP": "Please select the IP address that the client server will use to boot.",
+ "lang_commandLine": "Command line",
+ "lang_count": "Count",
+ "lang_downloadBootImage": "Download boot-image",
+ "lang_downloadRufus": "Download Rufus",
+ "lang_editBuiltinWarn": "WARNING! You're editing a predefined item. Future updates might reset your changes!",
+ "lang_editMenuHead": "Edit menu",
+ "lang_efiOnly": "EFI only",
+ "lang_entryChooserTitle": "Select menu item",
+ "lang_entryId": "ID",
+ "lang_entryTitle": "Title",
+ "lang_execAutoUnload": "Unload after execution (--autofree)",
+ "lang_execReplace": "Replace current iPXE stack (--replace)",
+ "lang_execResetConsole": "Reset console before execution",
+ "lang_forceRecompile": "Force recompile",
+ "lang_generationFailed": "Could not generate boot menu. The bwLehrpool-System might not work properly. If you can't fix the problem, please report the error log below to the bwLehrpool project.",
+ "lang_hotkey": "Hotkey",
+ "lang_idFormatHint": "(16 chars max, a-z 0-9 - _)",
+ "lang_imageToLoad": "Image to load (e.g. kernel)",
+ "lang_initRd": "Optional initrd\/initramfs to load",
+ "lang_ipxeWikiUrl": "at the iPXE wiki",
+ "lang_isDefault": "Default",
+ "lang_listOfMenus": "Menulist",
+ "lang_localBootDefault": "Default method to use for booting from disk",
+ "lang_localBootExceptions": "Exceptions to the local boot method, defined per system model",
+ "lang_localBootHead": "Boot from local disk",
+ "lang_localBootIntro": "There are several methods to trigger a local boot from the iPXE environment. In most cases, the \"AUTO\" setting will work, but with some system models it might be necessary to override the default behavior. In some instances, a BIOS update might resolve the issue as well.",
+ "lang_locationCount": "Number of Locations",
+ "lang_menuDeleteConfirm": "Are you sure you want to delete this menu?",
+ "lang_menuEntryOverride": "Override default selection",
+ "lang_menuGeneration": "Generating boot menu...",
+ "lang_menuListIntro": "This is the list of iPXE menus, with information about assigned locations. You can create, edit and delete additional menus.",
+ "lang_menuTimeout": "Timeout",
+ "lang_menuTitle": "Menu",
+ "lang_moduleHeading": "iPXE \/ Boot Menu",
+ "lang_newBootEntryHead": "New menu item",
+ "lang_newMenu": "New menu",
+ "lang_none": "(none)",
+ "lang_override": "Override",
+ "lang_recompileHint": "Recompile iPXE binaries now. Usually this happens automatically on changes, but if you suspect problems caused by outdated binaries, you can trigger recompilation here.",
+ "lang_refCount": "References",
+ "lang_referencingMenus": "Referencing menus",
+ "lang_scriptContent": "Script content",
+ "lang_seconds": "Seconds",
+ "lang_set": "Set",
+ "lang_spacer": "Spacer",
+ "lang_systemmodel": "System model",
+ "lang_title": "Title",
+ "lang_typeExecEntry": "Standardeintrag",
+ "lang_typeScriptEntry": "Custom script",
+ "lang_usbImage": "USB image",
+ "lang_usbImgHelp": "The USB image can be used to create a bootable USB stick, which enables you to boot bwLehrpool without changing your DHCP settings or enabling network boot in the clients. The only requirement is that you enable USB boot in the client's BIOS. The USB stick is only used for bootstrapping, the actual bwLehrpool system is still loaded via network from your local bwLehrpool server.",
+ "lang_usbImgHelpBtn": "Create bootable thumb drive",
+ "lang_usbImgHelpLinux": "On Linux you can simply use dd to write the image to a usb stick. The image already contains a partition table, so make sure you write the image to the device itself and not to an already existing partition (e.g. to \/dev\/sdx not \/dev\/sdx1)",
+ "lang_usbImgHelpWindows": "On Windows you need to use a 3rd party tool that can directly write to usb sticks. There are several free and open source soltions, one of them being Rufus. Rufus has been tested with the bwLehrpool image and is very simple to use. After launching Rufus, just open the downloaded USB image, select the proper USB stick to write to (be careful not to overwrite the wrong drive!), and you're ready to go.",
+ "lang_useDefaultMenu": "Inherit from parent location",
+ "lang_useDefaultMenuEntry": "(Menu default)"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/lang/pt/messages.json b/modules-available/serversetup-bwlp-ipxe/lang/pt/messages.json
index 65745768..65745768 100644
--- a/modules-available/serversetup-bwlp/lang/pt/messages.json
+++ b/modules-available/serversetup-bwlp-ipxe/lang/pt/messages.json
diff --git a/modules-available/serversetup-bwlp/lang/en/module.json b/modules-available/serversetup-bwlp-ipxe/lang/pt/module.json
index aeea610c..aeea610c 100644
--- a/modules-available/serversetup-bwlp/lang/en/module.json
+++ b/modules-available/serversetup-bwlp-ipxe/lang/pt/module.json
diff --git a/modules-available/serversetup-bwlp/lang/pt/template-tags.json b/modules-available/serversetup-bwlp-ipxe/lang/pt/template-tags.json
index 14788767..14788767 100644
--- a/modules-available/serversetup-bwlp/lang/pt/template-tags.json
+++ b/modules-available/serversetup-bwlp-ipxe/lang/pt/template-tags.json
diff --git a/modules-available/serversetup-bwlp-ipxe/page.inc.php b/modules-available/serversetup-bwlp-ipxe/page.inc.php
new file mode 100644
index 00000000..6f95d754
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/page.inc.php
@@ -0,0 +1,829 @@
+<?php
+
+class Page_ServerSetup extends Page
+{
+
+ private $addrListTask;
+ private $compileTask = null;
+ private $currentAddress;
+ private $currentMenu;
+ private $hasIpSet = false;
+
+ private function getCompileTask()
+ {
+ if ($this->compileTask !== null)
+ return $this->compileTask;
+ $this->compileTask = Property::get('ipxe-task-id');
+ if ($this->compileTask !== false) {
+ $this->compileTask = Taskmanager::status($this->compileTask);
+ if (!Taskmanager::isTask($this->compileTask) || Taskmanager::isFinished($this->compileTask)) {
+ $this->compileTask = false;
+ }
+ }
+ return $this->compileTask;
+ }
+
+ protected function doPreprocess()
+ {
+ User::load();
+
+ if (!User::isLoggedIn()) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
+
+ if (Request::any('action') === 'getimage') {
+ User::assertPermission("download");
+ $this->handleGetImage();
+ }
+
+ $this->currentMenu = Property::getBootMenu();
+
+ $action = Request::post('action');
+
+ if ($action === false) {
+ $this->currentAddress = Property::getServerIp();
+ $this->getLocalAddresses();
+ }
+
+ if ($action === 'compile') {
+ User::assertPermission("edit.address");
+ if ($this->getCompileTask() === false) {
+ Trigger::ipxe();
+ }
+ Util::redirect('?do=serversetup');
+ }
+
+ if ($action === 'ip') {
+ User::assertPermission("edit.address");
+ // New address is to be set
+ $this->getLocalAddresses();
+ $this->updateLocalAddress();
+ }
+
+ if ($action === 'savebootentry') {
+ User::assertPermission('ipxe.bootentry.edit');
+ $this->saveBootEntry();
+ }
+
+ if ($action === 'deleteBootentry') {
+ User::assertPermission('ipxe.bootentry.edit');
+ $this->deleteBootEntry();
+ }
+
+ if ($action === 'savemenu') {
+ User::assertPermission('ipxe.menu.edit');
+ $this->saveMenu();
+ }
+
+ if ($action === 'savelocation') {
+ // Permcheck in function
+ $this->saveLocationMenu();
+ Util::redirect('?do=locations');
+ }
+
+ if ($action === 'savelocalboot') {
+ User::assertPermission('ipxe.localboot.edit');
+ $this->saveLocalboot();
+ }
+
+ if ($action === 'deleteMenu') {
+ // Permcheck in function
+ $this->deleteMenu();
+ }
+
+ if ($action === 'setDefaultMenu') {
+ User::assertPermission('ipxe.menu.edit', 0);
+ $this->setDefaultMenu();
+ }
+
+ if (Request::isPost()) {
+ Util::redirect('?do=serversetup');
+ }
+
+ User::assertPermission('access-page');
+
+ if (User::hasPermission('ipxe.*')) {
+ Dashboard::addSubmenu('?do=serversetup&show=menu', Dictionary::translate('submenu_menu', true));
+ Dashboard::addSubmenu('?do=serversetup&show=bootentry', Dictionary::translate('submenu_bootentry', true));
+ }
+ if (User::hasPermission('edit.address')) {
+ Dashboard::addSubmenu('?do=serversetup&show=address', Dictionary::translate('submenu_address', true));
+ }
+ if (User::hasPermission('download')) {
+ Dashboard::addSubmenu('?do=serversetup&show=download', Dictionary::translate('submenu_download', true));
+ }
+ if (User::hasPermission('ipxe.localboot.*')) {
+ Dashboard::addSubmenu('?do=serversetup&show=localboot', Dictionary::translate('submenu_localboot', true));
+ }
+ if (Request::get('show') === false) {
+ $subs = Dashboard::getSubmenus();
+ if (empty($subs)) {
+ User::assertPermission('download');
+ } else {
+ Util::redirect($subs[0]['url']);
+ }
+ }
+ }
+
+ protected function doRender()
+ {
+ Render::addTemplate("heading");
+
+ $task = $this->getCompileTask();
+ if ($task !== false) {
+ $files = [];
+ if ($task['data'] && $task['data']['files']) {
+ foreach ($task['data']['files'] as $k => $v) {
+ $files[] = ['name' => $k, 'namehyphen' => str_replace(['/', '.'], '-', $k)];
+ }
+ }
+ Render::addTemplate('ipxe_update', array('taskid' => $task['id'], 'files' => $files));
+ }
+
+ switch (Request::get('show')) {
+ case 'editbootentry':
+ User::assertPermission('ipxe.bootentry.edit');
+ $this->showEditBootEntry();
+ break;
+ case 'editmenu':
+ User::assertPermission('ipxe.menu.view');
+ $this->showEditMenu();
+ break;
+ case 'download':
+ User::assertPermission('download');
+ $this->showDownload();
+ break;
+ case 'menu':
+ User::assertPermission('ipxe.menu.view');
+ $this->showMenuList();
+ break;
+ case 'bootentry':
+ User::assertPermission('ipxe.bootentry.view');
+ $this->showBootentryList();
+ break;
+ case 'address':
+ User::assertPermission('edit.address');
+ $this->showEditAddress();
+ break;
+ case 'assignlocation':
+ // Permcheck in function
+ $this->showEditLocation();
+ break;
+ case 'localboot':
+ User::assertPermission('ipxe.localboot.*');
+ $this->showLocalbootConfig();
+ break;
+ default:
+ Util::redirect('?do=serversetup');
+ break;
+ }
+ }
+
+ private function showDownload()
+ {
+ $list = glob('/srv/openslx/www/boot/download/*', GLOB_NOSORT);
+ usort($list, function ($a, $b) {
+ return strcmp(substr($a, -4), substr($b, -4)) * 100 + strcmp($a, $b);
+ });
+ $files = [];
+ $strings = [
+ 'efi' => [Dictionary::translate('dl-efi', true) => 50],
+ 'pcbios' => [Dictionary::translate('dl-pcbios', true) => 51],
+ 'usb' => [Dictionary::translate('dl-usb', true) => 80],
+ 'hd' => [Dictionary::translate('dl-hd', true) => 81],
+ 'lkrn' => [Dictionary::translate('dl-lkrn', true) => 82],
+ 'i386' => [Dictionary::translate('dl-i386', true) => 10],
+ 'x86_64' => [Dictionary::translate('dl-x86_64', true) => 11],
+ 'ecm' => [Dictionary::translate('dl-usbnic', true) => 60],
+ 'ncm' => [Dictionary::translate('dl-usbnic', true) => 61],
+ 'ipxe' => [Dictionary::translate('dl-pcinic', true) => 62],
+ 'snp' => [Dictionary::translate('dl-snp', true) => 63],
+ ];
+ foreach ($list as $file) {
+ if ($file{0} === '.')
+ continue;
+ if (is_file($file)) {
+ $base = basename($file);
+ $features = [];
+ foreach (preg_split('/[\-\.\/]+/', $base, -1, PREG_SPLIT_NO_EMPTY) as $p) {
+ if (array_key_exists($p, $strings)) {
+ $features += $strings[$p];
+ }
+ }
+ asort($features);
+ $files[] = [
+ 'name' => $base,
+ 'size' => Util::readableFileSize(filesize($file)),
+ 'modified' => Util::prettyTime(filemtime($file)),
+ 'class' => substr($base, -4) === '.usb' ? 'slx-bold' : '',
+ 'features' => implode(', ', array_keys($features)),
+ ];
+ }
+ }
+ Render::addTemplate('download', ['files' => $files]);
+ }
+
+ private function makeSelectArray($list, $default)
+ {
+ $ret = [];
+ foreach (array_keys($list) as $k) {
+ $ret[] = [
+ 'key' => $k,
+ 'selected' => ($k === $default ? 'selected' : ''),
+ ];
+ }
+ return $ret;
+ }
+
+ private function showLocalbootConfig()
+ {
+ // Default setting
+ $default = Property::get(Localboot::PROPERTY_KEY, 'AUTO');
+ if (!array_key_exists($default, Localboot::BOOT_METHODS)) {
+ $default = 'AUTO';
+ }
+ $optionList = $this->makeSelectArray(Localboot::BOOT_METHODS, $default);
+ // Exceptions
+ $cutoff = strtotime('-90 days');
+ $models = [];
+ $res = Database::simpleQuery('SELECT m.systemmodel, cnt, sl.bootmethod FROM (
+ SELECT m2.systemmodel, Count(*) AS cnt FROM machine m2
+ WHERE m2.lastseen > :cutoff
+ GROUP BY systemmodel
+ ) m
+ LEFT JOIN serversetup_localboot sl USING (systemmodel)
+ ORDER BY systemmodel', ['cutoff' => $cutoff]);
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $row['options'] = $this->makeSelectArray(Localboot::BOOT_METHODS, $row['bootmethod']);
+ $models[] = $row;
+ }
+ // Output
+ $data = [
+ 'default' => $default,
+ 'options' => $optionList,
+ 'exceptions' => $models,
+ ];
+ Render::addTemplate('localboot', $data);
+ }
+
+ private function showBootentryList()
+ {
+ $allowEdit = User::hasPermission('ipxe.bootentry.edit');
+
+ $res = Database::simpleQuery("SELECT be.entryid, be.hotkey, be.title, be.builtin, Count(*) AS refs FROM serversetup_bootentry be
+ INNER JOIN serversetup_menuentry sm USING (entryid)
+ GROUP BY be.entryid
+ ORDER BY be.title ASC");
+ $bootentryTable = [];
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $bootentryTable[] = $row;
+ }
+
+ Render::addTemplate('bootentry-list', array(
+ 'bootentryTable' => $bootentryTable,
+ 'allowEdit' => $allowEdit,
+ ));
+ }
+
+ private function showMenuList()
+ {
+ $allowedEdit = User::getAllowedLocations('ipxe.menu.edit');
+
+ // TODO Permission::addGlobalTags($perms, null, ['edit.menu', 'edit.address', 'download']);
+
+ $res = Database::simpleQuery("SELECT m.menuid, m.title, m.isdefault, GROUP_CONCAT(l.locationid) AS locations,
+ GROUP_CONCAT(ll.locationname SEPARATOR ', ') AS locnames
+ FROM serversetup_menu m
+ LEFT JOIN serversetup_menu_location l USING (menuid)
+ LEFT JOIN location ll USING (locationid)
+ GROUP BY menuid
+ ORDER BY title");
+ $menuTable = [];
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (empty($row['locations'])) {
+ $locations = [];
+ $row['allowEdit'] = in_array(0, $allowedEdit);
+ } else {
+ $locations = explode(',', $row['locations']);
+ $row['allowEdit'] = empty(array_diff($locations, $allowedEdit));
+ }
+ $row['locationCount'] = empty($locations) ? '' : count($locations);
+ $menuTable[] = $row;
+ }
+
+ Render::addTemplate('menu-list', array(
+ 'menuTable' => $menuTable,
+ 'showSetDefault' => User::hasPermission('ipxe.menu.edit', 0)
+ ));
+ }
+
+ private function hasMenuPermission($menuid, $permission)
+ {
+ $allowedEditLocations = User::getAllowedLocations($permission);
+ $allowEdit = in_array(0, $allowedEditLocations);
+ if (!$allowEdit) {
+ // Get locations
+ $locations = Database::queryColumnArray('SELECT locationid FROM serversetup_menu_location
+ WHERE menuid = :menuid', compact('menuid'));
+ if (!empty($locations)) {
+ $allowEdit = count(array_diff($locations, $allowedEditLocations)) === 0;
+ }
+ }
+ return $allowEdit;
+ }
+
+ private function showEditMenu()
+ {
+ $id = Request::get('id', false, 'int');
+ // if = edit, else = add new
+ if ($id !== 0) {
+ $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid, isdefault
+ FROM serversetup_menu WHERE menuid = :id", compact('id'));
+ } else {
+ $menu = [];
+ $menu['menuid'] = 0;
+ $menu['timeoutms'] = 0;
+ $menu['title'] = '';
+ $menu['defaultentryid'] = null;
+ $menu['isdefault'] = false;
+ }
+
+ if ($menu === false) {
+ Message::addError('invalid-menu-id', $id);
+ Util::redirect('?do=serversetup&show=menu');
+ }
+ $highlight = Request::get('highlight', false, 'string');
+ if ($id !== 0 && !$this->hasMenuPermission($id, 'ipxe.menu.edit')) {
+ $menu['readonly'] = 'readonly';
+ $menu['disabled'] = 'disabled';
+ $menu['plainpass'] = '';
+ }
+ if (!User::hasPermission('ipxe.menu.edit', 0)) {
+ $menu['globalMenuWarning'] = true;
+ }
+
+ $menu['timeout'] = round($menu['timeoutms'] / 1000);
+ $menu['entries'] = [];
+ $res = Database::simpleQuery("SELECT menuentryid, entryid, hotkey, title, hidden, sortval, plainpass FROM
+ serversetup_menuentry WHERE menuid = :id ORDER BY sortval ASC", compact('id'));
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['entryid'] == $highlight) {
+ $row['highlight'] = 'active';
+ }
+ $menu['entries'][] = $row;
+ }
+ $menu['keys'] = array_map(function ($item) { return ['key' => $item]; }, MenuEntry::getKeyList());
+ $menu['entrylist'] = Database::queryAll("SELECT entryid, title, hotkey, data FROM serversetup_bootentry ORDER BY title ASC");
+ foreach ($menu['entrylist'] as &$bootentry) {
+ //$bootentry['json'] = $bootentry['data'];
+ $bootentry['data'] = json_decode($bootentry['data'], true);
+ if (array_key_exists('arch', $bootentry['data'])) {
+ $bootentry['data']['PCBIOS'] = array('executable' => $bootentry['data']['executable']['PCBIOS'],
+ 'initRd' => $bootentry['data']['initRd']['PCBIOS'],
+ 'commandLine' => $bootentry['data']['commandLine']['PCBIOS']);
+ $bootentry['data']['EFI'] = array('executable' => $bootentry['data']['executable']['EFI'],
+ 'initRd' => $bootentry['data']['initRd']['EFI'],
+ 'commandLine' => $bootentry['data']['commandLine']['EFI']);
+
+ if ($bootentry['data']['arch'] === 'PCBIOS') {
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_biosOnly', true);
+ unset($bootentry['data']['EFI']);
+ } else if ($bootentry['data']['arch'] === 'EFI') {
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_efiOnly', true);
+ unset($bootentry['data']['PCBIOS']);
+ } else {
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archBoth', true);
+ }
+
+ } elseif (!array_key_exists('script', $bootentry['data'])) {
+ $bootentry['data']['arch'] = Dictionary::translateFile('template-tags','lang_archAgnostic', true);
+ $bootentry['data']['archAgnostic'] = array('executable' => $bootentry['data']['executable'],
+ 'initRd' => $bootentry['data']['initRd'],
+ 'commandLine' => $bootentry['data']['commandLine']);
+ }
+ }
+ foreach ($menu['entries'] as &$entry) {
+ $entry['isdefault'] = ($entry['menuentryid'] == $menu['defaultentryid']);
+ // TODO: plainpass only when permissions
+ }
+
+ Permission::addGlobalTags($menu['perms'], 0, ['ipxe.menu.edit']);
+ Render::addTemplate('menu-edit', $menu);
+ }
+
+ private function showEditBootEntry()
+ {
+ $params = [];
+ $id = Request::get('id', false, 'string');
+ if ($id === false) {
+ $params['exec_checked'] = 'checked';
+ $params['entryid'] = 'u-' . dechex(mt_rand(0x1000, 0xffff)) . '-' . dechex(time());
+ $params['entries'] = [
+ ['mode' => 'PCBIOS'],
+ ['mode' => 'EFI'],
+ ];
+ } else {
+ // Query existing entry
+ $row = Database::queryFirst('SELECT entryid, title, builtin, data FROM serversetup_bootentry
+ WHERE entryid = :id LIMIT 1', ['id' => $id]);
+ if ($row === false) {
+ Message::addError('invalid-boot-entry', $id);
+ Util::redirect('?do=serversetup');
+ }
+ $entry = BootEntry::fromJson($row['data']);
+ if ($entry === null) {
+ Message::addError('unknown-bootentry-type', $id);
+ Util::redirect('?do=serversetup');
+ }
+ $entry->addFormFields($params);
+ $params['title'] = $row['title'];
+ $params['entryid'] = $row['entryid'];
+ $params['builtin'] = $row['builtin'];
+ $params['menus'] = Database::queryAll('SELECT m.menuid, m.title FROM serversetup_menu m
+ INNER JOIN serversetup_menuentry me ON (me.menuid = m.menuid)
+ WHERE me.entryid = :entryid', ['entryid' => $row['entryid']]);
+ }
+
+ Render::addTemplate('ipxe-new-boot-entry', $params);
+ }
+
+ private function showEditAddress()
+ {
+ Render::addTemplate('ipaddress', array(
+ 'ips' => $this->addrListTask['data']['addresses'],
+ 'chooseHintClass' => $this->hasIpSet ? '' : 'alert alert-danger',
+ 'disabled' => ($this->getCompileTask() === false) ? '' : 'disabled',
+ ));
+ }
+
+ // -----------------------------------------------------------------------------------------------
+
+ private function getLocalAddresses()
+ {
+ $this->addrListTask = Taskmanager::submit('LocalAddressesList', array());
+
+ if ($this->addrListTask === false) {
+ $this->addrListTask['data']['addresses'] = false;
+ return false;
+ }
+
+ if (!Taskmanager::isFinished($this->addrListTask)) { // TODO: Async if just displaying
+ $this->addrListTask = Taskmanager::waitComplete($this->addrListTask['id'], 4000);
+ }
+
+ if (Taskmanager::isFailed($this->addrListTask) || !isset($this->addrListTask['data']['addresses'])) {
+ $this->addrListTask['data']['addresses'] = false;
+ return false;
+ }
+
+ $sortIp = array();
+ foreach (array_keys($this->addrListTask['data']['addresses']) as $key) {
+ $item = & $this->addrListTask['data']['addresses'][$key];
+ if (!isset($item['ip']) || !preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $item['ip']) || substr($item['ip'], 0, 4) === '127.') {
+ unset($this->addrListTask['data']['addresses'][$key]);
+ continue;
+ }
+ if ($this->currentAddress === $item['ip']) {
+ $item['default'] = true;
+ $this->hasIpSet = true;
+ }
+ $sortIp[] = $item['ip'];
+ }
+ unset($item);
+ array_multisort($sortIp, SORT_STRING, $this->addrListTask['data']['addresses']);
+ return true;
+ }
+
+ private function deleteBootEntry() {
+ $id = Request::post('deleteid', false, 'string');
+ if ($id === false) {
+ Message::addError('main.parameter-missing', 'deleteid');
+ return;
+ }
+ Database::exec("DELETE FROM serversetup_bootentry WHERE entryid = :entryid", array("entryid" => $id));
+ // TODO: Redirect to &show=bootentry
+ Message::addSuccess('bootentry-deleted');
+ }
+
+ private function setDefaultMenu()
+ {
+ $id = Request::post('menuid', false, 'int');
+ if ($id === false) {
+ Message::addError('main.parameter-missing', 'menuid');
+ return;
+ }
+ Database::exec('UPDATE serversetup_menu SET isdefault = (menuid = :menuid)', ['menuid' => $id]);
+ Message::addSuccess('menu-set-default');
+ }
+
+ private function deleteMenu()
+ {
+ $id = Request::post('deleteid', false, 'int');
+ if ($id === false) {
+ Message::addError('main.parameter-missing', 'deleteid');
+ return;
+ }
+ if (!$this->hasMenuPermission($id, 'ipxe.menu.edit')) {
+ Message::addError('locations.no-permission-location', $id);
+ return;
+ }
+ Database::exec("DELETE FROM serversetup_menu WHERE menuid = :menuid", array("menuid" => $id));
+ Message::addSuccess('menu-deleted');
+ }
+
+ private function saveMenu()
+ {
+ $id = Request::post('menuid', false, 'int');
+ if ($id === false) {
+ Message::addError('main.parameter-missing', 'menuid');
+ return;
+ }
+
+ $insertParams = [
+ 'title' => IPxe::sanitizeIpxeString(Request::post('title', '', 'string')),
+ 'timeoutms' => abs(Request::post('timeout', 0, 'int') * 1000),
+ ];
+ if ($id === 0) {
+ Database::exec("INSERT INTO serversetup_menu (title, timeoutms, isdefault) VALUES (:title, :timeoutms, 0)", $insertParams);
+ $menu['menuid'] = $id = Database::lastInsertId();
+ } else {
+ $menu = Database::queryFirst("SELECT m.menuid
+ FROM serversetup_menu m
+ WHERE menuid = :id", compact('id'));
+ if ($menu === false) {
+ Message::addError('invalid-menu-id', $id);
+ return;
+ }
+ $insertParams['menuid'] = $id;
+ Database::exec('UPDATE serversetup_menu SET title = :title, timeoutms = :timeoutms
+ WHERE menuid = :menuid', $insertParams);
+ }
+
+ $keepIds = [];
+ $entries = Request::post('entry', false, 'array');
+ $wantedDefaultEntryId = Request::post('defaultentry', null, 'string');
+ $defaultEntryId = null;
+
+ if ($entries) {
+ foreach ($entries as $key => $entry) {
+ if (!isset($entry['sortval'])) {
+ error_log(print_r($entry, true));
+ continue;
+ }
+ // Fallback defaults
+ $entry += [
+ 'entryid' => null,
+ 'title' => '',
+ 'hidden' => 0,
+ 'plainpass' => '',
+ ];
+ $params = [
+ 'title' => IPxe::sanitizeIpxeString($entry['title']),
+ 'sortval' => (int)$entry['sortval'],
+ 'menuid' => $menu['menuid'],
+ ];
+ if (empty($entry['entryid'])) {
+ // Spacer
+ $params += [
+ 'entryid' => null,
+ 'hotkey' => '',
+ 'hidden' => 0, // Doesn't make any sense
+ 'plainpass' => '', // Doesn't make any sense
+ ];
+ } else {
+ $params += [
+ 'entryid' => $entry['entryid'], // TODO validate?
+ 'hotkey' => MenuEntry::filterKeyName($entry['hotkey']),
+ 'hidden' => (int)$entry['hidden'], // TODO (needs hotkey to make sense)
+ 'plainpass' => $entry['plainpass'],
+ ];
+ }
+ if (is_numeric($key)) {
+ if ((string)$key === $wantedDefaultEntryId) { // Check now that we have generated our key
+ $defaultEntryId = $key;
+ }
+ $keepIds[] = $key;
+ $params['menuentryid'] = $key;
+ $params['md5pass'] = IPxe::makeMd5Pass($entry['plainpass'], $key);
+ $ret = Database::exec('UPDATE serversetup_menuentry
+ SET entryid = :entryid, hotkey = :hotkey, title = :title, hidden = :hidden, sortval = :sortval,
+ plainpass = :plainpass, md5pass = :md5pass
+ WHERE menuid = :menuid AND menuentryid = :menuentryid', $params, true);
+ } else {
+ $ret = Database::exec("INSERT INTO serversetup_menuentry
+ (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass)
+ VALUES (:menuid, :entryid, :hotkey, :title, :hidden, :sortval, :plainpass, '')", $params, true);
+ if ($ret) {
+ $newKey = Database::lastInsertId();
+ if ((string)$key === $wantedDefaultEntryId) { // Check now that we have generated our key
+ $defaultEntryId = $newKey;
+ }
+ $keepIds[] = (int)$newKey;
+ if (!empty($entry['plainpass'])) {
+ Database::exec('UPDATE serversetup_menuentry SET md5pass = :md5pass WHERE menuentryid = :id', [
+ 'md5pass' => IPxe::makeMd5Pass($entry['plainpass'], $newKey),
+ 'id' => $newKey,
+ ]);
+ }
+ }
+ }
+
+ if ($ret === false) {
+ Message::addWarning('error-saving-entry', $entry['title'], Database::lastError());
+ }
+ }
+ Database::exec('DELETE FROM serversetup_menuentry WHERE menuid = :menuid AND menuentryid NOT IN (:keep)',
+ ['menuid' => $menu['menuid'], 'keep' => $keepIds]);
+ // Set default entry
+ Database::exec('UPDATE serversetup_menu SET defaultentryid = :default WHERE menuid = :menuid',
+ ['menuid' => $menu['menuid'], 'default' => $defaultEntryId]);
+ } else {
+ Database::exec('DELETE FROM serversetup_menuentry WHERE menuid = :menuid', ['menuid' => $menu['menuid']]);
+ Database::exec('UPDATE serversetup_menu SET defaultentryid = NULL WHERE menuid = :menuid', ['menuid' => $menu['menuid']]);
+ }
+
+ Message::addSuccess('menu-saved');
+ }
+
+ private function updateLocalAddress()
+ {
+ $newAddress = Request::post('ip', 'none', 'string');
+ $valid = false;
+ foreach ($this->addrListTask['data']['addresses'] as $item) {
+ if ($item['ip'] !== $newAddress)
+ continue;
+ $valid = true;
+ break;
+ }
+ if ($valid) {
+ Property::setServerIp($newAddress);
+ Util::redirect('?do=ServerSetup');
+ } else {
+ Message::addError('invalid-ip', $newAddress);
+ }
+ Util::redirect();
+ }
+
+ private function handleGetImage()
+ {
+ $file = "/opt/openslx/ipxe/openslx-bootstick.raw";
+ if (!is_readable($file)) {
+ Message::addError('image-not-found');
+ return;
+ }
+ Header('Content-Type: application/octet-stream');
+ Header('Content-Disposition: attachment; filename="openslx-bootstick-' . Property::getServerIp() . '-raw.img"');
+ readfile($file);
+ exit;
+ }
+
+ private function saveBootEntry()
+ {
+ $oldEntryId = Request::post('entryid', false, 'string');
+ $newId = Request::post('newid', false, 'string');
+ if (!preg_match('/^[a-z0-9\-_]{1,16}$/', $newId)) {
+ Message::addError('main.parameter-empty', 'newid');
+ return;
+ }
+ $data = Request::post('entry', false);
+ if (!is_array($data)) {
+ Message::addError('missing-bootentry-data');
+ return;
+ }
+ $type = Request::post('type', false, 'string');
+ if ($type === 'exec') {
+ $entry = BootEntry::newStandardBootEntry($data);
+ } elseif ($type === 'script') {
+ $entry = BootEntry::newCustomBootEntry($data);
+ } else {
+ Message::addError('unknown-bootentry-type', $type);
+ return;
+ }
+ if ($entry === null) {
+ Message::addError('main.empty-field');
+ Util::redirect('?do=serversetup&show=bootentry');
+ }
+ $params = [
+ 'entryid' => $newId,
+ 'title' => Request::post('title', '', 'string'),
+ 'data' => json_encode($entry->toArray()),
+ ];
+ // New or update?
+ if (empty($oldEntryId)) {
+ // New entry
+ Database::exec('INSERT INTO serversetup_bootentry (entryid, title, builtin, data)
+ VALUES (:entryid, :title, 0, :data)', $params);
+ Message::addSuccess('boot-entry-created', $newId);
+ } else {
+ // Edit existing entry
+ $params['oldid'] = $oldEntryId;
+ Database::exec('UPDATE serversetup_bootentry SET entryid = :entryid, title = :title, data = :data
+ WHERE entryid = :oldid', $params);
+ Message::addSuccess('boot-entry-updated', $newId);
+ }
+ Util::redirect('?do=serversetup&show=bootentry');
+ }
+
+ private function showEditLocation()
+ {
+ $locationId = Request::get('locationid', false, 'int');
+ $loc = Location::get($locationId);
+ if ($loc === false) {
+ Message::addError('locations.invalid-location-id', $locationId);
+ return;
+ }
+ User::assertPermission('ipxe.menu.assign', $locationId);
+ // List of menu entries
+ $res = Database::simpleQuery('SELECT menuentryid, title FROM serversetup_menuentry');
+ $menuEntries = $res->fetchAll(PDO::FETCH_KEY_PAIR);
+ // List of menus
+ $data = [
+ 'locationid' => $locationId,
+ 'locationName' => $loc['locationname'],
+ ];
+ $res = Database::simpleQuery('SELECT m.menuid, m.title, ml.locationid, ml.defaultentryid, GROUP_CONCAT(me.menuentryid) AS entries FROM serversetup_menu m
+ LEFT JOIN serversetup_menu_location ml ON (m.menuid = ml.menuid AND ml.locationid = :locationid)
+ INNER JOIN serversetup_menuentry me ON (m.menuid = me.menuid AND me.entryid IS NOT NULL)
+ GROUP BY menuid
+ ORDER BY m.title ASC', ['locationid' => $locationId]);
+ $menus = [];
+ $hasDefault = false;
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $eids = explode(',', $row['entries']);
+ $row['entries'] = [];
+ foreach ($eids as $eid) {
+ $row['entries'][] = [
+ 'id' => $eid,
+ 'title' => $menuEntries[$eid],
+ 'selected' => ($eid == $row['defaultentryid'] ? 'selected' : ''),
+ ];
+ }
+ if ($row['locationid'] !== null) {
+ $hasDefault = true;
+ $row['menu_selected'] = 'checked';
+ }
+ $menus[] = $row;
+ }
+ if (!$hasDefault) {
+ $data['default_selected'] = 'checked';
+ }
+ $data['list'] = $menus;
+ Render::addTemplate('menu-assign-location', $data);
+ }
+
+ private function saveLocationMenu()
+ {
+ $locationId = Request::post('locationid', false, 'int');
+ $loc = Location::get($locationId);
+ if ($loc === false) {
+ Message::addError('locations.invalid-location-id', $locationId);
+ return;
+ }
+ User::assertPermission('ipxe.menu.assign', $locationId);
+ $menuId = Request::post('menuid', false, 'int');
+ if ($menuId === 0) {
+ Database::exec('DELETE FROM serversetup_menu_location WHERE locationid = :locationid',
+ ['locationid' => $locationId]);
+ Message::addSuccess('location-use-default', $loc['locationname']);
+ return;
+ }
+ $defaultEntryId = Request::post('defaultentryid-' . $menuId, 0, 'int');
+ if ($defaultEntryId === 0) {
+ $defaultEntryId = null;
+ }
+ Database::exec('INSERT INTO serversetup_menu_location (menuid, locationid, defaultentryid)
+ VALUES (:menuid, :locationid, :defaultentryid)
+ ON DUPLICATE KEY UPDATE menuid = :menuid, defaultentryid = :defaultentryid', [
+ 'menuid' => $menuId,
+ 'locationid' => $locationId,
+ 'defaultentryid' => $defaultEntryId
+ ]);
+ Message::addSuccess('location-menu-assigned', $loc['locationname']);
+ }
+
+ private function saveLocalboot()
+ {
+ $default = Request::post('default', 'AUTO', 'string');
+ if (!array_key_exists($default, Localboot::BOOT_METHODS)) {
+ Message::addError('localboot-invalid-method', $default);
+ return;
+ }
+ Property::set(Localboot::PROPERTY_KEY, $default);
+ $overrides = Request::post('override', [], 'array');
+ Database::exec('TRUNCATE TABLE serversetup_localboot');
+ foreach ($overrides as $model => $mode) {
+ if (empty($mode)) // No override
+ continue;
+ if (!array_key_exists($mode, Localboot::BOOT_METHODS)) {
+ Message::addWarning('localboot-invalid-method', $mode);
+ continue;
+ }
+ Database::exec('INSERT INTO serversetup_localboot (systemmodel, bootmethod)
+ VALUES (:model, :mode)', compact('model', 'mode'));
+ }
+ Message::addSuccess('localboot-saved');
+ Util::redirect('?do=serversetup&show=localboot');
+ }
+
+}
diff --git a/modules-available/serversetup-bwlp-ipxe/permissions/permissions.json b/modules-available/serversetup-bwlp-ipxe/permissions/permissions.json
new file mode 100644
index 00000000..33cc9cea
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/permissions/permissions.json
@@ -0,0 +1,29 @@
+{
+ "access-page": {
+ "location-aware": false
+ },
+ "download": {
+ "location-aware": false
+ },
+ "edit.address": {
+ "location-aware": false
+ },
+ "ipxe.bootentry.view": {
+ "location-aware": false
+ },
+ "ipxe.bootentry.edit": {
+ "location-aware": false
+ },
+ "ipxe.menu.view": {
+ "location-aware": false
+ },
+ "ipxe.menu.edit": {
+ "location-aware": false
+ },
+ "ipxe.menu.assign": {
+ "location-aware": true
+ },
+ "ipxe.localboot.edit": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/bootentry-list.html b/modules-available/serversetup-bwlp-ipxe/templates/bootentry-list.html
new file mode 100644
index 00000000..0cf005c5
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/bootentry-list.html
@@ -0,0 +1,83 @@
+<h2>{{lang_bootentryHead}}</h2>
+
+<p>
+ {{lang_bootentryIntro}}
+</p>
+
+<table class="table">
+ <thead>
+ <tr>
+ <th>{{lang_bootentryTitle}}</th>
+ <th>{{lang_hotkey}}</th>
+ <th class="slx-smallcol">{{lang_refCount}}</th>
+ <th class="slx-smallcol">{{lang_edit}}</th>
+ <th class="slx-smallcol">{{lang_delete}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#bootentryTable}}
+ <tr>
+ <td>
+ {{title}}
+ </td>
+ <td>
+ {{hotkey}}
+ </td>
+ <td align="right">
+ {{refs}}
+ </td>
+ <td align="center">
+ {{#allowEdit}}
+ <a href="?do=serversetup&amp;show=editbootentry&amp;id={{entryid}}" class="btn btn-xs btn-default">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ {{/allowEdit}}
+ </td>
+ <td align="center">
+ {{#allowEdit}}
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="deleteBootentry('{{entryid}}', '{{builtin}}')">
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ {{/allowEdit}}
+ </td>
+ </tr>
+ {{/bootentryTable}}
+ </tbody>
+</table>
+<div class="pull-right">
+ {{#allowEdit}}
+ <a href="?do=serversetup&amp;show=editbootentry" class="btn btn-success">
+ <span class="glyphicon glyphicon-plus"></span>
+ {{lang_addBootentry}}
+ </a>
+ {{/allowEdit}}
+</div>
+
+<!-- Modals -->
+<form method="post" action="?do=serversetup">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_bootentryDeleteConfirm}}</p>
+ </div>
+ <div class="modal-footer">
+ <input type="hidden" id="delete-bootentry-id" name="deleteid" value="">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="deleteBootentry" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+
+<script>
+ function deleteBootentry(entryid) {
+ $("#delete-bootentry-id").val(entryid);
+ }
+</script> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/download.html b/modules-available/serversetup-bwlp-ipxe/templates/download.html
new file mode 100644
index 00000000..62064b66
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/download.html
@@ -0,0 +1,53 @@
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_downloadBootImage}}
+ </div>
+ <div class="panel-body">
+ <table class="slx-table">
+ {{#files}}
+ <tr>
+ <td><a class="{{class}}" href="/boot/download/{{name}}">{{name}}</a></td>
+ <td class="text-right">{{size}}</td>
+ <td class="text-right">{{modified}}</td>
+ <td>({{features}})</td>
+ </tr>
+ {{/files}}
+ </table>
+ <p>
+ <span class="btn btn-default" data-toggle="modal" data-target="#help-usbimg">
+ <span class="glyphicon glyphicon-question-sign"></span>
+ {{lang_usbImgHelpBtn}}
+ </span>
+ </p>
+ <p>
+ {{lang_additionalInfoLink}} <a href="https://ipxe.org/appnote/buildtargets" target="_blank">{{lang_ipxeWikiUrl}}</a>
+ </p>
+ </div>
+</div>
+
+<div class="modal fade" id="help-usbimg" tabindex="-1" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ {{lang_usbImage}}
+ </div>
+ <div class="modal-body">
+ <p>{{lang_usbImgHelp}}</p>
+ <p>
+ <b>Linux</b>
+ <br>
+ {{lang_usbImgHelpLinux}}
+ </p>
+ <p>
+ <b>Windows</b>
+ <br>
+ {{lang_usbImgHelpWindows}}
+ </p>
+ <p>
+ <a href="https://rufus.akeo.ie/#download" target="_blank">{{lang_downloadRufus}}</a>
+ </p>
+ </div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/heading.html b/modules-available/serversetup-bwlp-ipxe/templates/heading.html
new file mode 100644
index 00000000..e2aa0bff
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/heading.html
@@ -0,0 +1,3 @@
+<div class="page-header">
+ <h1>{{lang_moduleHeading}}</h1>
+</div> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/ipaddress.html b/modules-available/serversetup-bwlp-ipxe/templates/ipaddress.html
new file mode 100644
index 00000000..ea19c417
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/ipaddress.html
@@ -0,0 +1,44 @@
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_bootAddress}}
+ </div>
+ <div class="panel-body">
+ <div class="{{chooseHintClass}}">
+ {{lang_chooseIP}}
+ </div>
+ <form method="post" action="?do=ServerSetup">
+ <input type="hidden" name="action" value="ip">
+ <input type="hidden" name="token" value="{{token}}">
+ <table class="slx-table">
+ {{#ips}}
+ <tr>
+ <td>{{ip}}</td>
+ {{#default}}
+ <td>
+ <span class="btn btn-success btn-xs"><span class="glyphicon glyphicon-ok"></span> {{lang_active}}</span>
+ </td>
+ {{/default}}
+ {{^default}}
+ <td>
+ <button class="btn btn-primary btn-xs" name="ip" value="{{ip}}" {{disabled}}>
+ <span class="glyphicon glyphicon-flag"></span>
+ {{lang_set}}
+ </button>
+ </td>
+ {{/default}}
+ </tr>
+ {{/ips}}
+ </table>
+ <p>
+ {{lang_recompileHint}}
+ </p>
+ </form>
+ <form method="post" action="?do=ServerSetup">
+ <input type="hidden" name="token" value="{{token}}">
+ <button class="btn btn-default" name="action" value="compile" {{disabled}}>
+ <span class="glyphicon glyphicon-refresh"></span>
+ {{lang_forceRecompile}}
+ </button>
+ </form>
+ </div>
+</div> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html b/modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html
new file mode 100644
index 00000000..7e82b5cc
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/ipxe-new-boot-entry.html
@@ -0,0 +1,165 @@
+<h2>{{lang_newBootEntryHead}}</h2>
+
+{{#builtin}}
+ <div class="alert alert-warning">
+ {{lang_editBuiltinWarn}}
+ </div>
+{{/builtin}}
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_bootEntryData}}
+ </div>
+ <div class="panel-body">
+ <form method="post" action="?do=serversetup">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="action" value="savebootentry">
+ <input type="hidden" name="entryid" value="{{entryid}}">
+
+ <div class="form-group">
+ <div class="radio">
+ <input class="type-radio" type="radio" name="type" value="exec" id="type-exec" {{exec_checked}}>
+ <label for="type-exec">{{lang_typeExecEntry}}</label>
+ </div>
+ <div class="radio">
+ <input class="type-radio" type="radio" name="type" value="script" id="type-script" {{script_checked}}>
+ <label for="type-script">{{lang_typeScriptEntry}}</label>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="input-id">
+ {{lang_entryId}} {{lang_idFormatHint}}
+ </label>
+ <input id="input-id" class="form-control" name="newid" value="{{entryid}}" pattern="^[a-z0-9\-_]{1,16}$" minlength="1" maxlength="16" required>
+ </div>
+ <div class="form-group">
+ <label for="input-title">
+ {{lang_entryTitle}}
+ </label>
+ <input id="input-title" class="form-control" name="title" value="{{title}}" maxlength="100">
+ </div>
+ <div class="form-group">
+ <label for="arch-selector">
+ {{lang_archSelector}}
+ </label>
+ <select id="arch-selector" class="form-control" name="entry[arch]">
+ <option value="agnostic" {{agnostic_selected}}>{{lang_archAgnostic}}</option>
+ <option value="PCBIOS" {{PCBIOS_selected}}>{{lang_biosOnly}}</option>
+ <option value="EFI" {{EFI_selected}}>{{lang_efiOnly}}</option>
+ <option value="PCBIOS-EFI" {{PCBIOS-EFI_selected}}>{{lang_archBoth}}</option>
+ </select>
+ </div>
+
+ <div class="type-form" id="form-exec">
+ <div class="row">
+ {{#entries}}
+ <div class="mode-class col-md-6" id="col-{{mode}}">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <h4 class="arch-heading">{{mode}}</h4>
+ <div class="form-group">
+ <label for="input-ex">
+ {{lang_imageToLoad}}
+ </label>
+ <input id="input-ex" class="form-control" name="entry[executable][{{mode}}]" value="{{executable}}">
+ </div>
+ <div class="form-group">
+ <label for="input-rd">
+ {{lang_initRd}}
+ </label>
+ <input id="input-rd" class="form-control" name="entry[initRd][{{mode}}]" value="{{initRd}}">
+ </div>
+ <div class="form-group">
+ <label for="input-cmd">
+ {{lang_commandLine}}
+ </label>
+ <input id="input-cmd" class="form-control" name="entry[commandLine][{{mode}}]"
+ value="{{commandLine}}">
+ </div>
+ <div class="form-group">
+ <div class="checkbox checkbox-inline">
+ <input id="exec-replace-{{mode}}" class="form-control" type="checkbox"
+ name="entry[replace][{{mode}}]" {{replace_checked}}>
+ <label for="exec-replace-{{mode}}">{{lang_execReplace}}</label>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="checkbox checkbox-inline">
+ <input id="exec-au-{{mode}}" class="form-control" type="checkbox"
+ name="entry[autoUnload][{{mode}}]" {{autoUnload_checked}}>
+ <label for="exec-au-{{mode}}">{{lang_execAutoUnload}}</label>
+ </div>
+ </div>
+ <div class="form-group">
+ <div class="checkbox checkbox-inline">
+ <input id="exec-reset-{{mode}}" class="form-control" type="checkbox"
+ name="entry[resetConsole][{{mode}}]" {{resetConsole_checked}}>
+ <label for="exec-reset-{{mode}}">{{lang_execResetConsole}}</label>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ {{/entries}}
+ </div>
+ </div>
+
+ <div class="type-form" id="form-script">
+ <div class="form-group">
+ <label for="script-ta">
+ {{lang_scriptContent}}
+ </label>
+ <textarea id="script-ta" class="form-control" rows="10"
+ name="entry[script]">{{entry.script}}</textarea>
+ </div>
+ </div>
+
+ {{#builtin}}
+ <div class="alert alert-warning">
+ {{lang_editBuiltinWarn}}
+ </div>
+ {{/builtin}}
+
+ <p class="slx-bold">{{lang_referencingMenus}}:</p>
+ <ul>
+ {{#menus}}
+ <a href="?do=serversetup&amp;show=editmenu&amp;id={{menuid}}&amp;highlight={{entryid}}">{{title}}</a>
+ {{/menus}}
+ </ul>
+
+ <div class="buttonbar text-right">
+ <button type="submit" class="btn btn-primary">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ </form>
+ </div>
+</div>
+
+<script><!--
+document.addEventListener('DOMContentLoaded', function () {
+ $('.type-radio').click(function () {
+ $('.type-form').hide();
+ $('#form-' + $(this).val()).show();
+ });
+ $('.type-radio[checked]').click();
+ var $as = $('#arch-selector');
+ $as.change(function() {
+ var v = $as.val();
+ if (v === 'agnostic') {
+ v = 'PCBIOS';
+ $('.arch-heading').hide();
+ } else {
+ $('.arch-heading').show();
+ }
+ var vs = v.split('-');
+ var cols = 12 / vs.length;
+ $('.mode-class').hide();
+ for (var i = 0; i < vs.length; ++i) {
+ $('#col-' + vs[i]).attr('class', 'mode-class col-md-' + cols).show();
+ }
+ }).change();
+});
+// --></script> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/ipxe_update.html b/modules-available/serversetup-bwlp-ipxe/templates/ipxe_update.html
new file mode 100644
index 00000000..344d3905
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/ipxe_update.html
@@ -0,0 +1,54 @@
+<div class="panel panel-default">
+ <div class="panel-heading">{{lang_menuGeneration}}</div>
+ <div class="panel-body">
+ <div id="file-list">
+ {{#files}}
+ <div id="built-{{namehyphen}}">
+ <span class="glyphicon glyphicon-question-sign"></span>
+ {{name}}
+ </div>
+ {{/files}}
+ </div>
+ <div id="genfailed" class="collapse">
+ <div class="alert alert-danger">
+ {{lang_generationFailed}}
+ </div>
+ </div>
+ <div id="tm-compile-div" data-tm-id="{{taskid}}" data-tm-log="log" data-tm-log-height="36em" data-tm-callback="ipxeGenCb">{{lang_menuGeneration}}</div>
+ </div>
+</div>
+
+<script type="text/javascript">
+ document.addEventListener('DOMContentLoaded', function() {
+ var slxFileList = $('#file-list').find('.glyphicon');
+ });
+
+ function ipxeGenCb(task)
+ {
+ if (!task || !task.statusCode)
+ return;
+
+ if (task.statusCode === 'TASK_FINISHED') {
+ $('#tm-compile-div').find('pre').hide();
+ }
+ if (task.statusCode === 'TASK_ERROR') {
+ var $gf = $('#genfailed');
+ if (task.data && task.data.errors) {
+ $gf.append($('<pre>').text(task.data.errors));
+ }
+ $gf.show('slow');
+ slxFileList.find('.glyphicon-question-sign').removeClass('glyphicon-question-sign').addClass('glyphicon-stop');
+ } else {
+ // Working or finished
+ if (task.data && task.data.files && task.data.files) {
+ for (var k in task.data.files) {
+ if (!task.data.files[k])
+ continue;
+ var f = '#built-' + k.replace('/', '-').replace('.', '-');
+ var $e = $(f);
+ $e.find('.glyphicon-question-sign').removeClass('glyphicon-question-sign').addClass('glyphicon-ok text-success');
+ }
+ }
+ }
+ }
+</script>
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/localboot.html b/modules-available/serversetup-bwlp-ipxe/templates/localboot.html
new file mode 100644
index 00000000..3037de2a
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/localboot.html
@@ -0,0 +1,59 @@
+<h2>{{lang_localBootHead}}</h2>
+
+<p>{{lang_localBootIntro}}</p>
+
+<form method="post" action="?do=serversetup">
+
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="action" value="savelocalboot">
+
+ <br>
+ <div class="form-group">
+ <label for="default-selector">
+ {{lang_localBootDefault}}
+ </label>
+ <select id="default-selector" class="form-control" name="default">
+ {{#options}}
+ <option {{selected}}>{{key}}</option>
+ {{/options}}
+ </select>
+ </div>
+
+ <br>
+ <h3>
+ {{lang_localBootExceptions}}
+ </h3>
+ <table class="table">
+ <tr>
+ <th>{{lang_systemmodel}}</th>
+ <th class="slx-smallcol">{{lang_count}}</th>
+ <th class="slx-smallcol">{{lang_override}}</th>
+ </tr>
+ {{#exceptions}}
+ <tr>
+ <td><a href="?do=statistics&show=list&filters=systemmodel+%3D+{{systemmodel}}">{{systemmodel}}</a></td>
+ <td class="text-right">{{cnt}}</td>
+ <td>
+ <select class="form-control" name="override[{{systemmodel}}]">
+ <option value="" {{^bootmethod}}selected{{/bootmethod}}>{{lang_none}}</option>
+ {{#options}}
+ <option {{selected}}>{{key}}</option>
+ {{/options}}
+ </select>
+ </td>
+ </tr>
+ {{/exceptions}}
+ </table>
+
+ <div class="text-right">
+ <button class="btn btn-warning" type="reset">
+ <span class="glyphicon glyphicon-refresh"></span>
+ {{lang_reset}}
+ </button>
+ <button class="btn btn-primary" type="submit">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+
+</form>
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/menu-assign-location.html b/modules-available/serversetup-bwlp-ipxe/templates/menu-assign-location.html
new file mode 100644
index 00000000..077d137e
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/menu-assign-location.html
@@ -0,0 +1,69 @@
+<h2>{{lang_assignMenuToLocation}}</h2>
+<h3>{{locationName}}</h3>
+
+<form method="post" action="?do=serversetup">
+
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="action" value="savelocation">
+ <input type="hidden" name="locationid" value="{{locationid}}">
+ <table class="table">
+ <thead>
+ <tr>
+ <th class="slx-smallcol"></th>
+ <th>{{lang_menuTitle}}</th>
+ <th class="slx-smallcol">{{lang_menuEntryOverride}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <div class="radio radio-inline">
+ <input type="radio" name="menuid" value="0" {{default_selected}}>
+ <label></label>
+ </div>
+ </td>
+ <td>
+ <i>{{lang_useDefaultMenu}}</i>
+ </td>
+ <td></td>
+ </tr>
+ {{#list}}
+ <tr>
+ <td>
+ <div class="radio radio-inline">
+ <input type="radio" name="menuid" value="{{menuid}}" {{menu_selected}}>
+ <label></label>
+ </div>
+ </td>
+ <td>
+ {{title}}
+ </td>
+ <td class="text-right">
+ <select name="defaultentryid-{{menuid}}" class="form-control">
+ <option value="0" style="font-style:italic">{{lang_useDefaultMenuEntry}}</option>
+ {{#entries}}
+ <option value="{{id}}" {{selected}}>{{title}}</option>
+ {{/entries}}
+ </select>
+ </td>
+ </tr>
+ {{/list}}
+ </tbody>
+ </table>
+
+ <div class="pull-right">
+ <button type="submit" class="btn btn-primary">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+
+</form>
+
+<div class="clearfix"></div>
+
+<script>
+ function deleteMenu(menuid) {
+ $("#delete-menu-id").val(menuid);
+ }
+</script> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html b/modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html
new file mode 100644
index 00000000..1598a2b7
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/menu-edit.html
@@ -0,0 +1,368 @@
+<h2>{{lang_editMenuHead}}</h2>
+
+<input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="position:absolute;top:-2000px" tabindex="-1">
+<input type="password" name="password_fake" id="password_fake" value="" style="position:absolute;top:-2000px" tabindex="-1">
+
+<div class="panel panel-default">
+ <div class="panel-heading">
+ {{title}}
+ {{^title}}
+ {{lang_newMenu}}
+ {{/title}}
+ </div>
+ <div class="panel-body list-group">
+ <form method="post" action="?do=serversetup">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="action" value="savemenu">
+ <input type="hidden" name="menuid" value="{{menuid}}">
+
+ <div class="row list-group-item">
+ <div class="col-sm-3">
+ <label for="panel-title">{{lang_menuTitle}}</label>
+ </div>
+ <div class="col-sm-9">
+ <input class="form-control" name="title" id="panel-title" type="text" value="{{title}}" {{readonly}}>
+ </div>
+ </div>
+ <div class="row list-group-item">
+ <div class="col-sm-3">
+ <label for="panel-timeout">{{lang_menuTimeout}}</label>
+ </div>
+ <div class="col-sm-9">
+ <div class="input-group">
+ <input class="form-control" name="timeout" id="panel-timeout" type="number" min="0" max="9999"
+ value="{{timeout}}" {{readonly}}>
+ <span class="input-group-addon">{{lang_seconds}}</span>
+ </div>
+ </div>
+ </div>
+ <div>
+ <table class="table">
+ <thead>
+ <tr>
+ <th class="slx-smallcol"></th>
+ <th class="slx-smallcol"></th>
+ <th class="slx-smallcol">{{lang_entryId}}</th>
+ <th>{{lang_title}}</th>
+ <th width="11%">{{lang_hotkey}}</th>
+ <th width="15%">{{lang_password}}</th>
+ <th class="slx-smallcol"><span class="glyphicon glyphicon-eye-close"></span></th>
+ <th class="slx-smallcol"></th>
+ </tr>
+ </thead>
+ <tbody id="table-body" style="overflow: auto;">
+ {{#entries}}
+ <tr class="{{highlight}}">
+ <input type="hidden" class="sort-val" name="entry[{{menuentryid}}][sortval]" value="{{sortval}}">
+ <input type="hidden" name="entry[{{menuentryid}}][hidden]" value="0">
+ <td class="drag-handler" style="cursor: pointer;text-align: center; vertical-align: middle;">
+ <span class="glyphicon glyphicon-th-list"></span>
+ </td>
+
+ <td class="slx-smallcol" style="text-align: center; vertical-align: middle;">
+ <div class="radio radio-inline no-spacer" style="margin: 0;{{^entryid}}display: none;{{/entryid}}">
+ <input type="radio" name="defaultentry" value="{{menuentryid}}"
+ {{#isdefault}}checked{{/isdefault}} {{perms.ipxe.menu.edit.disabled}} {{disabled}}>
+ <label></label>
+ </div>
+ </td>
+
+ <td class="text-nowrap">
+ <input class="entry-id" type="hidden" name="entry[{{menuentryid}}][entryid]" value="{{entryid}}">
+ <button type="button" class="btn btn-default" style="width: 100%; text-align: left" {{disabled}} data-toggle="modal" data-target="#entry-chooser-modal">
+ {{#entryid}}
+ {{entryid}}
+ {{/entryid}}
+ {{^entryid}}
+ {{lang_spacer}}
+ {{/entryid}}
+ </button>
+ </td>
+ <td>
+ <input class="form-control title" name="entry[{{menuentryid}}][title]" value="{{title}}"
+ maxlength="100" {{readonly}}>
+ </td>
+
+ <td>
+ <select class="form-control key-list no-spacer" {{^entryid}}style="display: none;"{{/entryid}} name="entry[{{menuentryid}}][hotkey]" {{readonly}} data-default="{{hotkey}}">
+ </select>
+ </td>
+
+ <td>
+ <input class="form-control no-spacer" {{^entryid}}style="display: none;"{{/entryid}} name="entry[{{menuentryid}}][plainpass]" type="{{password_type}}"
+ value="{{plainpass}}" {{readonly}}>
+ </td>
+ <td class="slx-smallcol" style="text-align: center; vertical-align: middle;">
+ <div class="checkbox checkbox-inline no-spacer" style="text-align: left;margin: 0;{{^entryid}}display: none;{{/entryid}}">
+ <input name="entry[{{menuentryid}}][hidden]" value="1" type="checkbox" {{#hidden}}checked{{/hidden}}>
+ <label></label>
+ </div>
+ </td>
+ <td class="slx-smallcol" style="text-align: center; vertical-align: middle;">
+ <button type="button" class="btn btn-default remove-button"><span class="glyphicon glyphicon-remove"></span></button>
+ </td>
+ </tr>
+ {{/entries}}
+ </tbody>
+ </table>
+ </div>
+ <div class="text-right" style="margin-bottom: 20px">
+ <button id="add-btn" type="button" class="btn btn-success" {{disabled}}>
+ <span class="glyphicon glyphicon-plus-sign"></span>
+ {{lang_add}}
+ </button>
+ </div>
+ <div class="text-right">
+ <a href="?do=serversetup&show=menu" type="button" class="btn btn-default">{{lang_cancel}}</a>
+ <button id="save-button" type="submit" class="btn btn-primary" {{disabled}}>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ </form>
+
+ <div class="modal fade" id="entry-chooser-modal" tabindex="-1" role="dialog">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title">{{lang_entryChooserTitle}}</h5>
+ </div>
+ <div class="modal-body">
+ <div class="form-group">
+ <select id="entry-list" class="form-control">
+ <option value="">{{lang_spacer}}</option>
+ {{#entrylist}}
+ <option value="{{entryid}}">{{entryid}}</option>
+ {{/entrylist}}
+ </select>
+ </div>
+ {{#entrylist}}
+ <div id="entrydata-{{entryid}}" class="entrydata">
+ <div class="form-group">
+ <label for="{{entryid}}-name">{{lang_entryTitle}}</label>
+ <pre id="{{entryid}}-name">{{title}}</pre>
+ </div>
+ {{#data}}
+ {{#script}}
+ <div class="form-group">
+ <label for="{{entryid}}-script">{{lang_scriptContent}}</label>
+ <pre id="{{entryid}}-script">{{.}}</pre>
+ </div>
+ {{/script}}
+ {{^script}}
+ <div class="form-group">
+ <label for="{{entryid}}-script">{{lang_archSelector}}</label>
+ <pre id="{{entryid}}-arch">{{arch}}</pre>
+ </div>
+ {{#archAgnostic}}
+ <div class="form-group">
+ <label for="{{entryid}}-executable">{{lang_imageToLoad}}</label>
+ <pre id="{{entryid}}-executable">{{executable}}</pre>
+ </div>
+ <div class="form-group">
+ <label for="{{entryid}}-initRd">{{lang_initRd}}</label>
+ <pre id="{{entryid}}-initRd">{{initRd}}</pre>
+ </div>
+ <div class="form-group">
+ <label for="{{entryid}}-commandLine">{{lang_commandLine}}</label>
+ <pre id="{{entryid}}-commandLine" >{{commandLine}}</pre>
+ </div>
+ {{/archAgnostic}}
+ {{#PCBIOS}}
+ <div class="panel panel-default">
+ <div class="panel-heading">PCBIOS</div>
+ <div class="panel-body">
+ <div class="form-group">
+ <label for="{{entryid}}-executable">{{lang_imageToLoad}}</label>
+ <pre id="{{entryid}}-executable">{{executable}}</pre>
+ </div>
+ <div class="form-group">
+ <label for="{{entryid}}-initRd">{{lang_initRd}}</label>
+ <pre id="{{entryid}}-initRd">{{initRd}}</pre>
+ </div>
+ <div class="form-group">
+ <label for="{{entryid}}-commandLine">{{lang_commandLine}}</label>
+ <pre id="{{entryid}}-commandLine" >{{commandLine}}</pre>
+ </div>
+ </div>
+ </div>
+ {{/PCBIOS}}
+ {{#EFI}}
+ <div class="panel panel-default">
+ <div class="panel-heading">EFI</div>
+ <div class="panel-body">
+ <div class="form-group">
+ <label for="{{entryid}}-executable">{{lang_imageToLoad}}</label>
+ <pre id="{{entryid}}-executable">{{executable}}</pre>
+ </div>
+ <div class="form-group">
+ <label for="{{entryid}}-initRd">{{lang_initRd}}</label>
+ <pre id="{{entryid}}-initRd">{{initRd}}</pre>
+ </div>
+ <div class="form-group">
+ <label for="{{entryid}}-commandLine">{{lang_commandLine}}</label>
+ <pre id="{{entryid}}-commandLine" >{{commandLine}}</pre>
+ </div>
+ </div>
+ </div>
+ {{/EFI}}
+ {{/script}}
+ {{/data}}
+ </div>
+ {{/entrylist}}
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="button" class="btn btn-primary" id="choose-entry">{{lang_save}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+<div class="hidden">
+ <select id="key-list-template">
+ <option value="">{{lang_none}}</option>
+ {{#keys}}
+ <option value="{{key}}">{{key}}</option>
+ {{/keys}}
+ </select>
+</div>
+<table class="hidden" id="row-template">
+ <tr>
+ <input type="hidden" class="sort-val" name="entry[%new%][sortval]" value="99999">
+ <td class="drag-handler" style="cursor: pointer;text-align: center; vertical-align: middle;">
+ <span class="glyphicon glyphicon-th-list"></span>
+ </td>
+
+ <td class="slx-smallcol" style="text-align: center; vertical-align: middle;">
+ <div class="radio radio-inline no-spacer" style="margin: 0; display: none;">
+ <input type="radio" name="defaultentry" value="%new%">
+ <label></label>
+ </div>
+ </td>
+
+ <td class="text-nowrap">
+ <input class="entry-id" type="hidden" name="entry[%new%][entryid]" value="">
+ <button type="button" class="btn btn-default" style="width: 100%; text-align: left" {{disabled}} data-toggle="modal" data-target="#entry-chooser-modal">
+ {{lang_spacer}}
+ </button>
+ </td>
+ <td>
+ <input class="form-control title" data-old="#new#" name="entry[%new%][title]" maxlength="100">
+ </td>
+ <td>
+ <select class="form-control key-list no-spacer" style="display: none;" name="entry[%new%][hotkey]">
+ </select>
+ </td>
+ <td>
+ <input class="form-control no-spacer" style="display: none;" name="entry[%new%][plainpass]" type="{{password_type}}">
+ </td>
+ <td class="slx-smallcol" style="text-align: center; vertical-align: middle;">
+ <div class="checkbox checkbox-inline no-spacer" style="text-align: left;margin: 0;{{^entryid}}display: none;{{/entryid}}">
+ <input name="entry[%new%][hidden]" value="1" type="checkbox">
+ <label></label>
+ </div>
+ </td>
+ <td class="slx-smallcol" style="text-align: center; vertical-align: middle;">
+ <button type="button" class="btn btn-default remove-button"><span class="glyphicon glyphicon-remove"></span></button>
+ </td>
+ </tr>
+</table>
+
+<script type="text/javascript">
+ var spacerText = "{{lang_spacer}}";
+
+ document.addEventListener("DOMContentLoaded", function() {
+
+ function reassignSortValues() {
+ var startValue = 1;
+ $('.sort-val').each(function(index, element) {
+ element.value = startValue * 10;
+ startValue++;
+ });
+ }
+
+ $('#table-body').sortable({
+ opacity: 0.8,
+ handle: '.drag-handler',
+ start: function(evt, ui) {
+ ui.placeholder.css("visibility", "visible");
+ ui.placeholder.css("opacity", "0.152");
+ ui.placeholder.css("background-color", "#ddd");
+ },
+ stop: reassignSortValues
+ });
+
+ $('.key-list').each(function() {
+ $select = $(this);
+ $source = $('#key-list-template').find('option');
+ var def = $select.data('default');
+ $select.append($source.clone(true));
+ $select.find('option[value="' + def + '"]').attr('selected', true);
+ });
+ var newIndex = 0;
+ $('#add-btn').click(function() {
+ var $new = $('#row-template').find('tr').clone(true);
+ newIndex++;
+ $('#table-body').append($new);
+ $new.find('[name]').each(function() {
+ var $this = $(this);
+ var val = $this.val();
+ var name = $this.attr('name');
+ if (name) {
+ $this.attr('name', name.replace('%new%', 'new-' + newIndex));
+ }
+ if (val) {
+ $this.val(val.replace('%new%', 'new-' + newIndex));
+ }
+ });
+ reassignSortValues();
+ });
+
+ $('.remove-button').click(function() {
+ $(this).parent().parent().remove();
+ reassignSortValues();
+ });
+
+ $('#entry-list').change(function(e) {
+ var modal = $('#entry-chooser-modal');
+ modal.find('.entrydata').hide();
+ modal.find('#entrydata-' + $(this).val()).show();
+ });
+
+ var currentEntryButton = null;
+
+ $('#entry-chooser-modal').on('show.bs.modal', function(e) {
+ currentEntryButton = $(e.relatedTarget);
+ var entryId = currentEntryButton.parent().find('.entry-id').val();
+ $('#entry-list').val(entryId).change();
+ });
+
+ $('#choose-entry').click(function() {
+ $('#entry-chooser-modal').modal('hide');
+ var entryId = $('#entry-list').val();
+ currentEntryButton.parent().find('.entry-id').val(entryId);
+ currentEntryButton.text(entryId || spacerText);
+ var tableRow = currentEntryButton.parent().parent();
+ if (!entryId) {
+ tableRow.find('.no-spacer').hide();
+ tableRow.find('input.no-spacer').val('');
+ tableRow.find('div.no-spacer').find('input').prop('checked', false);
+
+ } else {
+ tableRow.find('.no-spacer').show();
+ }
+ var $title = tableRow.find('.title');
+ var oldval = $title.data('old');
+ if (oldval === '#stop#')
+ return;
+ if (oldval !== '#new#' && oldval !== $title.val()) {
+ $title.data('old', '#stop#');
+ return;
+ }
+ var text = $('#' + entryId + '-name').text();
+ $title.val(text).data('old', text);
+ });
+ });
+</script> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-ipxe/templates/menu-list.html b/modules-available/serversetup-bwlp-ipxe/templates/menu-list.html
new file mode 100644
index 00000000..545f22a9
--- /dev/null
+++ b/modules-available/serversetup-bwlp-ipxe/templates/menu-list.html
@@ -0,0 +1,100 @@
+<h2>{{lang_listOfMenus}}</h2>
+
+<p>
+ {{lang_menuListIntro}}
+</p>
+
+<table class="table">
+ <thead>
+ <tr>
+ <th>{{lang_menuTitle}}</th>
+ <th class="slx-smallcol">{{lang_locationCount}}</th>
+ <th class="slx-smallcol">{{lang_isDefault}}</th>
+ <th class="slx-smallcol">{{lang_edit}}</th>
+ <th class="slx-smallcol">{{lang_delete}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#menuTable}}
+ <tr>
+ <td>
+ {{title}}
+ </td>
+ <td class="text-right">
+ <span class="badge" data-toggle="tooltip" data-placement="top" title="{{locnames}}">{{locationCount}}</span>
+ </td>
+ <td align="center">
+ {{^isdefault}}
+ {{#showSetDefault}}
+ <form method="post" action="?do=serversetup">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="menuid" value="{{menuid}}">
+ <button type="submit" name="action" value="setDefaultMenu" class="btn btn-xs btn-info">
+ <span class="glyphicon glyphicon-flag"></span>
+ </button>
+ </form>
+ {{/showSetDefault}}
+ {{/isdefault}}
+ {{#isdefault}}
+ <span class="glyphicon glyphicon-ok"></span>
+ {{/isdefault}}
+ </td>
+ <td align="center">
+ {{#allowEdit}}
+ <a href="?do=serversetup&amp;show=editmenu&amp;id={{menuid}}" class="btn btn-xs btn-default">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ {{/allowEdit}}
+ </td>
+ <td align="center">
+ {{#allowDelete}}
+ <button type="button" class="btn btn-xs btn-danger" data-toggle="modal" data-target="#deleteModal" onclick="deleteMenu('{{menuid}}')">
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
+ {{/allowDelete}}
+ </td>
+ </tr>
+ {{/menuTable}}
+ </tbody>
+</table>
+<div class="pull-right">
+ <a href="?do=serversetup&amp;show=editmenu&amp;id=0" class="btn btn-success {{allowAddMenu}}">
+ <span class="glyphicon glyphicon-plus"></span>
+ {{lang_addMenu}}
+ </a>
+</div>
+
+<div class="clearfix"></div>
+
+
+<!-- Modals -->
+<form method="post" action="?do=serversetup">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class ="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+ <div class="modal-dialog" role="document">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+ <h4 class="modal-title" id="myModalLabel">{{lang_delete}}</h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_menuDeleteConfirm}}</p>
+ </div>
+ <div class="modal-footer">
+ <input type="hidden" id="delete-menu-id" name="deleteid" value="">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" name="action" value="deleteMenu" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</button>
+ </div>
+ </div>
+ </div>
+ </div>
+</form>
+
+<script>
+ function deleteMenu(menuid) {
+ $("#delete-menu-id").val(menuid);
+ }
+ document.addEventListener('DOMContentLoaded', function() {
+ $('[data-toggle="tooltip"]').tooltip();
+ });
+</script> \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-pxelinux/config.json b/modules-available/serversetup-bwlp-pxelinux/config.json
new file mode 100644
index 00000000..36268c6a
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/config.json
@@ -0,0 +1,3 @@
+{
+ "category": "main.settings-server"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-pxelinux/hooks/ipxe-update.inc.php b/modules-available/serversetup-bwlp-pxelinux/hooks/ipxe-update.inc.php
new file mode 100644
index 00000000..baa7a1bf
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/hooks/ipxe-update.inc.php
@@ -0,0 +1,9 @@
+<?php
+
+$data = Property::getBootMenu();
+$data['ipaddress'] = Property::getServerIp();
+$task = Taskmanager::submit('CompileIPxeLegacy', $data);
+if (!isset($task['id']))
+ return false;
+Property::set('ipxe-task-id', $task['id'], 15);
+return $task['id']; \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-pxelinux/hooks/main-warning.inc.php b/modules-available/serversetup-bwlp-pxelinux/hooks/main-warning.inc.php
new file mode 100644
index 00000000..a2eba6ff
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/hooks/main-warning.inc.php
@@ -0,0 +1,6 @@
+<?php
+
+if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', Property::getServerIp())) {
+ Message::addError('serversetup.no-ip-addr-set', true);
+ $needSetup = true;
+}
diff --git a/modules-available/serversetup-bwlp-pxelinux/inc/ipxe.inc.php b/modules-available/serversetup-bwlp-pxelinux/inc/ipxe.inc.php
new file mode 100644
index 00000000..c42de80b
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/inc/ipxe.inc.php
@@ -0,0 +1,224 @@
+<?php
+
+
+class Ipxe
+{
+
+ /**
+ * Takes a (partial) pxelinux menu and parses it into
+ * a PxeMenu object.
+ * @param string $input The pxelinux menu to parse
+ * @return PxeMenu the parsed menu
+ */
+ public static function parsePxeLinux($input)
+ {
+ /*
+ LABEL openslx-debug
+ MENU LABEL ^bwLehrpool-Umgebung starten (nosplash, debug)
+ KERNEL http://IPADDR/boot/default/kernel
+ INITRD http://IPADDR/boot/default/initramfs-stage31
+ APPEND slxbase=boot/default
+ IPAPPEND 3
+ */
+ $menu = new PxeMenu;
+ $sectionPropMap = [
+ 'menu label' => ['string', 'title'],
+ 'menu default' => ['true', 'isDefault'],
+ 'menu hide' => ['true', 'isHidden'],
+ 'menu disabled' => ['true', 'isDisabled'],
+ 'menu indent' => ['int', 'indent'],
+ 'kernel' => ['string', 'kernel'],
+ 'initrd' => ['string', 'initrd'],
+ 'append' => ['string', 'append'],
+ 'ipappend' => ['int', 'ipAppend'],
+ 'localboot' => ['int', 'localBoot'],
+ ];
+ $globalPropMap = [
+ 'timeout' => ['int', 'timeoutMs', 100],
+ 'totaltimeout' => ['int', 'totalTimeoutMs', 100],
+ 'menu title' => ['string', 'title'],
+ 'menu clear' => ['true', 'menuClear'],
+ 'menu immediate' => ['true', 'immediateHotkeys'],
+ 'ontimeout' => ['string', 'timeoutLabel'],
+ ];
+ $lines = preg_split('/[\r\n]+/', $input);
+ $section = null;
+ $count = count($lines);
+ for ($li = 0; $li < $count; ++$li) {
+ $line =& $lines[$li];
+ if (!preg_match('/^\s*([^m]\S*|menu\s+\S+)(\s+.*?|)\s*$/i', $line, $out))
+ continue;
+ $key = trim($out[1]);
+ $key = strtolower($key);
+ $key = preg_replace('/\s+/', ' ', $key);
+ if ($key === 'label') {
+ if ($section !== null) {
+ $menu->sections[] = $section;
+ }
+ $section = new PxeSection($out[2]);
+ } elseif ($key === 'menu separator') {
+ if ($section !== null) {
+ $menu->sections[] = $section;
+ $section = null;
+ }
+ $menu->sections[] = new PxeSection(null);
+ } elseif (self::handleKeyword($key, $out[2], $globalPropMap, $menu)) {
+ continue;
+ } elseif ($section === null) {
+ continue;
+ } elseif ($key === 'text' && strtolower($out[2]) === 'help') {
+ $text = '';
+ while (++$li < $count) {
+ $line =& $lines[$li];
+ if (strtolower(trim($line)) === 'endtext')
+ break;
+ $text .= $line . "\n";
+ }
+ $section->helpText = $text;
+ } elseif (self::handleKeyword($key, $out[2], $sectionPropMap, $section)) {
+ continue;
+ }
+ }
+ if ($section !== null) {
+ $menu->sections[] = $section;
+ }
+ return $menu;
+ }
+
+ /**
+ * Check if keyword is valid and if so, add its interpreted value
+ * to the given object. The map to look up the keyword has to be passed
+ * as well as the object to set the value in. Map and object should
+ * obviously match.
+ * @param string $key keyword of parsed line
+ * @param string $val raw value of currently parsed line (empty if not present)
+ * @param array $map Map in which $key is looked up as key
+ * @param PxeMenu|PxeSection The object to set the parsed and sanitized value in
+ * @return bool true if the value was found in the map (and set in the object), false otherwise
+ */
+ private static function handleKeyword($key, $val, $map, $object)
+ {
+ if (!isset($map[$key]))
+ return false;
+ $opt = $map[$key];
+ // opt[0] is the type the value should be cast to; special case "true" means
+ // this is a bool option that will be set as soon as the keyword is present,
+ // as it doesn't have any parameters
+ if ($opt[0] === 'true') {
+ $val = true;
+ } else {
+ settype($val, $opt[0]);
+ }
+ // If opt[2] is present it's a multiplier for the value
+ if (isset($opt[2])) {
+ $val *= $opt[2];
+ }
+ $object->{$opt[1]} = $val;
+ return true;
+ }
+
+}
+
+/**
+ * Class representing a parsed pxelinux menu. Members
+ * will be set to their annotated type if present or
+ * be null otherwise, except for present-only boolean
+ * options, which will default to false.
+ */
+class PxeMenu
+{
+ /**
+ * @var string menu title, shown at the top of the menu
+ */
+ public $title;
+ /**
+ * @var int initial timeout after which $timeoutLabel would be executed
+ */
+ public $timeoutMs;
+ /**
+ * @var int if the user canceled the timeout by pressing a key, this timeout would still eventually
+ * trigger and launch the $timeoutLabel section
+ */
+ public $totalTimeoutMs;
+ /**
+ * @var string label of section which will execute if the timeout expires
+ */
+ public $timeoutLabel;
+ /**
+ * @var bool hide menu and just show background after triggering an entry
+ */
+ public $menuClear = false;
+ /**
+ * @var bool boot the associated entry directly if its corresponding hotkey is presed instead of just highlighting
+ */
+ public $immediateHotkeys = false;
+ /**
+ * @var PxeSection[] list of sections the menu contains
+ */
+ public $sections = [];
+}
+
+/**
+ * Class representing a parsed pxelinux menu entry. Members
+ * will be set to their annotated type if present or
+ * be null otherwise, except for present-only boolean
+ * options, which will default to false.
+ */
+class PxeSection
+{
+ /**
+ * @var string label used internally in PXEMENU definition to address this entry
+ */
+ public $label;
+ /**
+ * @var string MENU LABEL of PXEMENU - title of entry displayed to the user
+ */
+ public $title;
+ /**
+ * @var int Number of spaces to prefix the title with
+ */
+ public $indent;
+ /**
+ * @var string help text to display when the entry is highlighted
+ */
+ public $helpText;
+ /**
+ * @var string Kernel to load
+ */
+ public $kernel;
+ /**
+ * @var string initrd to load for the kernel
+ */
+ public $initrd;
+ /**
+ * @var string command line options to pass to the kernel
+ */
+ public $append;
+ /**
+ * @var int IPAPPEND from PXEMENU. Bitmask of valid options 1 and 2.
+ */
+ public $ipAppend;
+ /**
+ * @var string Password protecting the entry. This is most likely in crypted form.
+ */
+ public $passwd;
+ /**
+ * @var bool whether this section is marked as default (booted after timeout)
+ */
+ public $isDefault = false;
+ /**
+ * @var bool Menu entry is not visible (can only be triggered by timeout)
+ */
+ public $isHidden = false;
+ /**
+ * @var bool Disable this entry, making it unselectable
+ */
+ public $isDisabled = false;
+ /**
+ * @var int Value of the LOCALBOOT field
+ */
+ public $localBoot;
+
+ public function __construct($label) { $this->label = $label; }
+}
+
diff --git a/modules-available/serversetup-bwlp/lang/de/messages.json b/modules-available/serversetup-bwlp-pxelinux/lang/de/messages.json
index 3e2cc834..3e2cc834 100644
--- a/modules-available/serversetup-bwlp/lang/de/messages.json
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/de/messages.json
diff --git a/modules-available/serversetup-bwlp/lang/de/module.json b/modules-available/serversetup-bwlp-pxelinux/lang/de/module.json
index da71d558..da71d558 100644
--- a/modules-available/serversetup-bwlp/lang/de/module.json
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/de/module.json
diff --git a/modules-available/serversetup-bwlp-pxelinux/lang/de/permissions.json b/modules-available/serversetup-bwlp-pxelinux/lang/de/permissions.json
new file mode 100644
index 00000000..98baec3c
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/de/permissions.json
@@ -0,0 +1,6 @@
+{
+ "access-page": "Seite sehen.",
+ "download": "USB-Image herunterladen.",
+ "edit.address": "Boot-Adresse des Servers ausw\u00e4hlen.",
+ "edit.menu": "Bootmen\u00fc anpassen."
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/lang/de/template-tags.json b/modules-available/serversetup-bwlp-pxelinux/lang/de/template-tags.json
index f80febb0..8d612ab0 100644
--- a/modules-available/serversetup-bwlp/lang/de/template-tags.json
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/de/template-tags.json
@@ -11,7 +11,7 @@
"lang_downloadImage": "USB-Image herunterladen",
"lang_downloadRufus": "Rufus herunterladen",
"lang_example": "Beispiel",
- "lang_generationFailed": "Erzeugen des Bootmen\u00fcs fehlgeschlagen. Der Netzwerkboot von bwLehrpool wird wahrscheinlich nicht funktionieren. Wenn Sie den Fehler nicht selbst beheben k\u00f6nnen, melden Sie bitte obenstehende Fehlermeldung an das bwLehrpool-Projekt.",
+ "lang_generationFailed": "Erzeugen des Bootmen\u00fcs fehlgeschlagen. Der Netzwerkboot von bwLehrpool wird wahrscheinlich nicht funktionieren. Wenn Sie den Fehler nicht selbst beheben k\u00f6nnen, melden Sie bitte die Logausgabe an das bwLehrpool-Projekt.",
"lang_localHDD": "Lokale HDD",
"lang_masterPassword": "Master-Passwort",
"lang_masterPasswordHelp": "Das Master-Passwort wird ben\u00f6tigt, um einen Booteintrag direkt am Client tempor\u00e4r durch Dr\u00fccken der Tab-Taste zu editieren. Da dies f\u00fcr Manipulation am Client genutzt werden kann, sollte diese Funktion unbedingt mit einem Passwort gesch\u00fctzt werden.",
@@ -21,9 +21,11 @@
"lang_menuCustomHint3": "und w\u00e4hlen Sie als Standard-Bootverhalten ebenfalls custom.",
"lang_menuDisplayTime": "Anzeigedauer des Men\u00fcs",
"lang_menuGeneration": "Erzeugen des Bootmen\u00fcs",
- "lang_moduleHeading": "iPXE / Boot Menu",
+ "lang_moduleHeading": "iPXE \/ Boot Menu",
+ "lang_pxeBuilt": "PXE-Binary gebaut",
"lang_seconds": "Sekunden",
"lang_set": "Setzen",
+ "lang_usbBuilt": "USB-Image gebaut",
"lang_usbImage": "USB-Image",
"lang_usbImgHelp": "Mit dem USB-Image k\u00f6nnen Sie einen bootbaren USB-Stick erstellen, \u00fcber den sich bwLehrpool an Rechnern starten l\u00e4sst, die keinen Netzwerkboot unterst\u00fctzen, bzw. f\u00fcr die keine entsprechende DHCP-Konfiguration vorhanden ist. Dies erfordert dann lediglich, dass in der BIOS-Konfiguration des Rechners USB-Boot zugelassen ist. Der Stick dient dabei lediglich als Einstiegspunkt; es ist nach wie vor ein bwLehrpool-Satellitenserver f\u00fcr den eigentlichen Bootvorgang von N\u00f6ten.",
"lang_usbImgHelpLinux": "Nutzen Sie dd, um das Image auf einen USB-Stick zu schreiben. Das Image enth\u00e4lt bereits eine Partitionstabelle, achten Sie daher darauf, dass Sie das Image z.B. nach \/dev\/sdx schreiben, und nicht nach \/dev\/sdx1",
diff --git a/modules-available/serversetup-bwlp/lang/en/messages.json b/modules-available/serversetup-bwlp-pxelinux/lang/en/messages.json
index d4ba6905..d4ba6905 100644
--- a/modules-available/serversetup-bwlp/lang/en/messages.json
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/en/messages.json
diff --git a/modules-available/serversetup-bwlp/lang/pt/module.json b/modules-available/serversetup-bwlp-pxelinux/lang/en/module.json
index aeea610c..aeea610c 100644
--- a/modules-available/serversetup-bwlp/lang/pt/module.json
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/en/module.json
diff --git a/modules-available/serversetup-bwlp-pxelinux/lang/en/permissions.json b/modules-available/serversetup-bwlp-pxelinux/lang/en/permissions.json
new file mode 100644
index 00000000..44d1c519
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/en/permissions.json
@@ -0,0 +1,6 @@
+{
+ "access-page": "View page.",
+ "download": "Download USB Image.",
+ "edit.address": "Choose boot address of the server.",
+ "edit.menu": "Customize boot menu."
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/lang/en/template-tags.json b/modules-available/serversetup-bwlp-pxelinux/lang/en/template-tags.json
index 1948718b..9bb55f93 100644
--- a/modules-available/serversetup-bwlp/lang/en/template-tags.json
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/en/template-tags.json
@@ -11,7 +11,7 @@
"lang_downloadImage": "Download USB Image",
"lang_downloadRufus": "Download Rufus",
"lang_example": "Example",
- "lang_generationFailed": "Could not generate boot menu. The bwLehrpool-System might not work properly. If you can't fix the problem, please report the error message above to the bwLehrpool project.",
+ "lang_generationFailed": "Could not generate boot menu. The bwLehrpool-System might not work properly. If you can't fix the problem, please report the error log below to the bwLehrpool project.",
"lang_localHDD": "Local HDD",
"lang_masterPassword": "Master Password",
"lang_masterPasswordHelp": "The master password is required to edit a boot menu entry. This should be set for security reasons.",
@@ -21,9 +21,11 @@
"lang_menuCustomHint3": "and select as the default boot behavior custom as well.",
"lang_menuDisplayTime": "Menu Display Time",
"lang_menuGeneration": "Generating boot menu...",
- "lang_moduleHeading": "iPXE / Boot Menu",
+ "lang_moduleHeading": "iPXE \/ Boot Menu",
+ "lang_pxeBuilt": "Built PXE binary",
"lang_seconds": "Seconds",
"lang_set": "Set",
+ "lang_usbBuilt": "Built USB image",
"lang_usbImage": "USB image",
"lang_usbImgHelp": "The USB image can be used to create a bootable USB stick, which enables you to boot bwLehrpool without changing your DHCP settings or enabling network boot in the clients. The only requirement is that you enable USB boot in the client's BIOS. The USB stick is only used for bootstrapping, the actual bwLehrpool system is still loaded via network from your local bwLehrpool server.",
"lang_usbImgHelpLinux": "On Linux you can simply use dd to write the image to a usb stick. The image already contains a partition table, so make sure you write the image to the device itself and not to an already existing partition (e.g. to \/dev\/sdx not \/dev\/sdx1)",
diff --git a/modules-available/serversetup-bwlp-pxelinux/lang/pt/messages.json b/modules-available/serversetup-bwlp-pxelinux/lang/pt/messages.json
new file mode 100644
index 00000000..65745768
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/pt/messages.json
@@ -0,0 +1,3 @@
+{
+ "invalid-ip": "Nenhuma interface est\u00e1 configurada com o endere\u00e7o {{0}}"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-pxelinux/lang/pt/module.json b/modules-available/serversetup-bwlp-pxelinux/lang/pt/module.json
new file mode 100644
index 00000000..aeea610c
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/pt/module.json
@@ -0,0 +1,3 @@
+{
+ "module_name": "iPXE \/ Boot Menu"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp-pxelinux/lang/pt/template-tags.json b/modules-available/serversetup-bwlp-pxelinux/lang/pt/template-tags.json
new file mode 100644
index 00000000..14788767
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/lang/pt/template-tags.json
@@ -0,0 +1,38 @@
+{
+ "lang_active": "Ativo",
+ "lang_bootAddress": "Endere\u00e7o Boot do Servidor",
+ "lang_bootBehavior": "Comportamento Padr\u00e3o de Boot",
+ "lang_bootHint": "O menu de boot deve ser recriado ap\u00f3s alterar o endere\u00e7o IP. Geralmente isso \u00e9 feito automaticamente, mas o processo tamb\u00e9m pode ser acionado manualmente na se\u00e7\u00e3o do menu de boot.",
+ "lang_bootInfo": "Aqui ajustes podem ser feitos na apar\u00eancia do menu de boot.",
+ "lang_bootMenu": "Menu de Boot",
+ "lang_bootMenuCreate": "Criar Menu de Boot",
+ "lang_chooseIP": "Por favor, selecione o endere\u00e7o IP que o servidor do cliente utilizar\u00e1 realizar o boot.",
+ "lang_close": "Fechar",
+ "lang_compile": "Compilar",
+ "lang_compileIso": "Compilar .iso",
+ "lang_compileKkpxe": "Compilar .kkpxe",
+ "lang_compileUsb": "Compilar .usb",
+ "lang_compilingIpxe": "Compilando iPXE",
+ "lang_customScript": "Script Customizado",
+ "lang_download": "Baixar",
+ "lang_example": "Exemplo",
+ "lang_extension": "Extens\u00e3o",
+ "lang_ipxeAdv": "Gerar iPXE no Modo Avan\u00e7ado",
+ "lang_ipxeInfo": "Aqui \u00e9 poss\u00edvel compilar e baixar o iPXE utilizando um script customiz\u00e1vel.",
+ "lang_ipxeSmp": "Gerar iPXE no Modo Simples",
+ "lang_ipxeSmpInfo": "Aqui voc\u00ea pode escolher gerar o iPXE escolhendo apenas uma das extens\u00f5es abaixo",
+ "lang_ipxeWarning": "Se esta for a primeira vez compilando, poder\u00e1 levar entre 1 e 4 minutos para que termine.",
+ "lang_loading": "Carregando",
+ "lang_localHDD": "HDD Local",
+ "lang_menuCustom": "Menu Adicional Customizado",
+ "lang_menuCustomHint1": "Aqui voc\u00ea tem a oportunidade de adicionar seu pr\u00f3prio c\u00f3digo de menu para o menu PXE exibido, por exemplo, para se referir a outro servidor PXE. O formato corresponde ao formato de menu syslinux.",
+ "lang_menuCustomHint2": "Voc\u00ea pode criar uma ou mais entradas. Se voc\u00ea quiser criar uma entrada que \u00e9 iniciada automaticamente quando o usu\u00e1rio faz uma sele\u00e7\u00e3o, atribua como",
+ "lang_menuCustomHint3": "e selecione como o comportamento de boot padr\u00e3o tamb\u00e9m my-entry.",
+ "lang_menuDisplayTime": "Tempo de Exibi\u00e7\u00e3o do Menu",
+ "lang_mountIpxe": "Montar iPXE",
+ "lang_restoreDefault": "Restaurar Padr\u00e3o",
+ "lang_saveScript": "Salvar Script",
+ "lang_seconds": "Segundos",
+ "lang_set": "Definir",
+ "lang_success": "Arquivo criado com sucesso:"
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/page.inc.php b/modules-available/serversetup-bwlp-pxelinux/page.inc.php
index 16d3f8e2..52b3afe4 100644
--- a/modules-available/serversetup-bwlp/page.inc.php
+++ b/modules-available/serversetup-bwlp-pxelinux/page.inc.php
@@ -17,7 +17,8 @@ class Page_ServerSetup extends Page
Util::redirect('?do=Main');
}
- if (Request::any('action') === 'getimage' && User::hasPermission("download")) {
+ if (Request::any('action') === 'getimage') {
+ User::assertPermission("download");
$this->handleGetImage();
}
@@ -30,32 +31,52 @@ class Page_ServerSetup extends Page
$this->getLocalAddresses();
}
- if ($action === 'ip' && User::hasPermission("edit.address")) {
+ if ($action === 'ip') {
+ User::assertPermission("edit.address");
// New address is to be set
$this->getLocalAddresses();
$this->updateLocalAddress();
}
- if ($action === 'ipxe' && User::hasPermission("edit.menu")) {
+ if ($action === 'ipxe') {
+ User::assertPermission("edit.menu");
// iPXE stuff changes
$this->updatePxeMenu();
}
+
+ if (Request::isPost()) {
+ Util::redirect('?do=serversetup');
+ }
+
+ User::assertPermission('access-page');
}
protected function doRender()
{
Render::addTemplate("heading");
- $taskid = Request::any('taskid');
- if ($taskid !== false && Taskmanager::isTask($taskid)) {
- Render::addTemplate('ipxe_update', array('taskid' => $taskid));
+ $task = Property::get('ipxe-task-id');
+ if ($task !== false) {
+ $task = Taskmanager::status($task);
+ if (!Taskmanager::isTask($task) || Taskmanager::isFinished($task)) {
+ $task = false;
+ }
}
+ if ($task !== false) {
+ Render::addTemplate('ipxe_update', array('taskid' => $task['id']));
+ }
+
+ Permission::addGlobalTags($perms, null, ['edit.menu', 'edit.address', 'download']);
Render::addTemplate('ipaddress', array(
'ips' => $this->taskStatus['data']['addresses'],
'chooseHintClass' => $this->hasIpSet ? '' : 'alert alert-danger',
'editAllowed' => User::hasPermission("edit.address"),
+ 'perms' => $perms,
));
$data = $this->currentMenu;
+ if (!User::hasPermission('edit.menu')) {
+ unset($data['masterpasswordclear']);
+ }
if (!isset($data['defaultentry'])) {
$data['defaultentry'] = 'net';
}
@@ -68,8 +89,7 @@ class Page_ServerSetup extends Page
if ($data['defaultentry'] === 'custom') {
$data['active-custom'] = 'checked';
}
- $data['editAllowed'] = User::hasPermission("edit.menu");
- $data['downloadAllowed'] = User::hasPermission("download");
+ $data['perms'] = $perms;
Render::addTemplate('ipxe', $data);
}
@@ -123,9 +143,7 @@ class Page_ServerSetup extends Page
}
if ($valid) {
Property::setServerIp($newAddress);
- global $tidIpxe;
- if (isset($tidIpxe) && $tidIpxe !== false)
- Util::redirect('?do=ServerSetup&taskid=' . $tidIpxe);
+ Util::redirect('?do=ServerSetup');
} else {
Message::addError('invalid-ip', $newAddress);
}
@@ -149,8 +167,8 @@ class Page_ServerSetup extends Page
else
$this->currentMenu['masterpassword'] = Crypto::hash6($this->currentMenu['masterpasswordclear']);
Property::setBootMenu($this->currentMenu);
- $id = Trigger::ipxe();
- Util::redirect('?do=ServerSetup&taskid=' . $id);
+ Trigger::ipxe();
+ Util::redirect('?do=ServerSetup');
}
private function handleGetImage()
diff --git a/modules-available/serversetup-bwlp-pxelinux/permissions/permissions.json b/modules-available/serversetup-bwlp-pxelinux/permissions/permissions.json
new file mode 100644
index 00000000..44927506
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/permissions/permissions.json
@@ -0,0 +1,14 @@
+{
+ "access-page": {
+ "location-aware": false
+ },
+ "download": {
+ "location-aware": false
+ },
+ "edit.address": {
+ "location-aware": false
+ },
+ "edit.menu": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/templates/heading.html b/modules-available/serversetup-bwlp-pxelinux/templates/heading.html
index d68360f1..d68360f1 100644
--- a/modules-available/serversetup-bwlp/templates/heading.html
+++ b/modules-available/serversetup-bwlp-pxelinux/templates/heading.html
diff --git a/modules-available/serversetup-bwlp/templates/ipaddress.html b/modules-available/serversetup-bwlp-pxelinux/templates/ipaddress.html
index e82253f5..8d73dfac 100644
--- a/modules-available/serversetup-bwlp/templates/ipaddress.html
+++ b/modules-available/serversetup-bwlp-pxelinux/templates/ipaddress.html
@@ -1,4 +1,4 @@
-<div class="panel panel-default {{^editAllowed}}disabledPanel{{/editAllowed}}">
+<div class="panel panel-default">
<div class="panel-heading">
{{lang_bootAddress}}
</div>
@@ -20,7 +20,10 @@
{{/default}}
{{^default}}
<td>
- <button class="btn btn-primary btn-xs" name="ip" value="{{ip}}"><span class="glyphicon glyphicon-flag"></span> {{lang_set}}</button>
+ <button class="btn btn-primary btn-xs" name="ip" value="{{ip}}" {{perms.edit.address.disabled}}>
+ <span class="glyphicon glyphicon-flag"></span>
+ {{lang_set}}
+ </button>
</td>
{{/default}}
</tr>
diff --git a/modules-available/serversetup-bwlp/templates/ipxe.html b/modules-available/serversetup-bwlp-pxelinux/templates/ipxe.html
index e0dc53e5..f4b0b4d3 100644
--- a/modules-available/serversetup-bwlp/templates/ipxe.html
+++ b/modules-available/serversetup-bwlp-pxelinux/templates/ipxe.html
@@ -3,7 +3,7 @@
<input type="password" name="password_fake" id="password_fake" value="" style="position:absolute;top:-2000px" tabindex="-1">
<input type="hidden" name="action" value="ipxe">
<input type="hidden" name="token" value="{{token}}">
- <div class="panel panel-default {{^editAllowed}}disabledPanel{{/editAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">
{{lang_bootMenu}}
</div>
@@ -16,15 +16,15 @@
<div class="form-group">
<strong>{{lang_bootBehavior}}</strong>
<div class="radio">
- <input type="radio" name="defaultentry" value="net" {{active-net}} id="id-net">
+ <input type="radio" name="defaultentry" value="net" {{active-net}} id="id-net" {{perms.edit.menu.disabled}}>
<label for="id-net">bwLehrpool</label>
</div>
<div class="radio">
- <input type="radio" name="defaultentry" value="hdd" {{active-hdd}} id="id-hdd">
+ <input type="radio" name="defaultentry" value="hdd" {{active-hdd}} id="id-hdd" {{perms.edit.menu.disabled}}>
<label for="id-hdd">{{lang_localHDD}}</label>
</div>
<div class="radio">
- <input type="radio" name="defaultentry" value="custom" {{active-custom}} id="id-custom">
+ <input type="radio" name="defaultentry" value="custom" {{active-custom}} id="id-custom" {{perms.edit.menu.disabled}}>
<label for="id-custom">{{lang_customEntry}} (&quot;custom&quot;)</label>
</div>
</div>
@@ -32,7 +32,7 @@
<div class="form-group">
<strong>{{lang_menuDisplayTime}}</strong>
<div class="input-group form-narrow">
- <input type="text" class="form-control" name="timeout" value="{{timeout}}" pattern="\d+">
+ <input type="text" class="form-control" name="timeout" value="{{timeout}}" pattern="\d+" {{perms.edit.menu.readonly}}>
<span class="input-group-addon">{{lang_seconds}}</span>
</div>
</div>
@@ -40,22 +40,22 @@
<div class="form-group">
<strong>{{lang_masterPassword}}</strong>
<div class="form-narrow">
- <input type="{{password_type}}" class="form-control" name="masterpassword" value="{{masterpasswordclear}}">
+ <input type="{{password_type}}" class="form-control" name="masterpassword" value="{{masterpasswordclear}}" {{perms.edit.menu.readonly}}>
</div>
<i>{{lang_masterPasswordHelp}}</i>
</div>
<div class="form-group">
<strong>{{lang_menuCustom}}</strong> <a class="btn btn-default btn-xs" data-toggle="modal" data-target="#help-custom"><span class="glyphicon glyphicon-question-sign"></span></a>
- <textarea class="form-control" name="custom" rows="8">{{custom}}</textarea>
+ <textarea class="form-control" name="custom" rows="8" {{perms.edit.menu.readonly}}>{{custom}}</textarea>
</div>
</div>
<div class="panel-footer">
- <button class="btn btn-primary pull-right" name="action" value="ipxe" {{^editAllowed}}disabled{{/editAllowed}}>{{lang_bootMenuCreate}}</button>
+ <button class="btn btn-primary pull-right" name="action" value="ipxe" {{perms.edit.menu.disabled}}>{{lang_bootMenuCreate}}</button>
<div>
<div class="btn-group" role="group">
- <a class="btn btn-default {{^downloadAllowed}}disabled{{/downloadAllowed}}" href="?do=ServerSetup&amp;action=getimage">
+ <a class="btn btn-default {{perms.download.disabled}}" href="?do=ServerSetup&amp;action=getimage">
<span class="glyphicon glyphicon-download-alt"></span>
{{lang_downloadImage}}
</a>
diff --git a/modules-available/serversetup-bwlp-pxelinux/templates/ipxe_update.html b/modules-available/serversetup-bwlp-pxelinux/templates/ipxe_update.html
new file mode 100644
index 00000000..c5aafa1c
--- /dev/null
+++ b/modules-available/serversetup-bwlp-pxelinux/templates/ipxe_update.html
@@ -0,0 +1,38 @@
+<div class="panel panel-default">
+ <div class="panel-heading">{{lang_menuGeneration}}</div>
+ <div class="panel-body">
+ <div id="built-pxe" class="invisible">
+ <span class="glyphicon glyphicon-ok"></span>
+ {{lang_pxeBuilt}}
+ </div>
+ <div id="built-usb" class="invisible">
+ <span class="glyphicon glyphicon-ok"></span>
+ {{lang_usbBuilt}}
+ </div>
+ <div id="genfailed" class="collapse">
+ <div class="alert alert-danger">
+ {{lang_generationFailed}}
+ </div>
+ </div>
+ <div data-tm-id="{{taskid}}" data-tm-log="log" data-tm-log-height="31em" data-tm-callback="ipxeGenCb">{{lang_menuGeneration}}</div>
+ </div>
+</div>
+
+<script type="text/javascript">
+ function ipxeGenCb(task)
+ {
+ if (!task || !task.statusCode)
+ return;
+ if (task.data) {
+ if (task.data.pxeDone) $('#built-pxe').removeClass('invisible');
+ if (task.data.usbDone) $('#built-usb').removeClass('invisible');
+ }
+ if (task.statusCode === 'TASK_ERROR') {
+ var $gf = $('#genfailed');
+ if (task.data && task.data.errors) {
+ $gf.append($('<pre>').text(task.data.errors));
+ }
+ $gf.show('slow');
+ }
+ }
+</script>
diff --git a/modules-available/serversetup-bwlp/config.json b/modules-available/serversetup-bwlp/config.json
deleted file mode 100644
index 7205d70a..00000000
--- a/modules-available/serversetup-bwlp/config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "category":"main.settings-server"
-}
diff --git a/modules-available/serversetup-bwlp/inc/ipxe.inc.php b/modules-available/serversetup-bwlp/inc/ipxe.inc.php
deleted file mode 100644
index abeea748..00000000
--- a/modules-available/serversetup-bwlp/inc/ipxe.inc.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-
-class Ipxe
-{
-
- public static function parsePxeLinux($input)
- {
- /*
- LABEL openslx-debug
- MENU LABEL ^bwLehrpool-Umgebung starten (nosplash, debug)
- KERNEL http://IPADDR/boot/default/kernel
- INITRD http://IPADDR/boot/default/initramfs-stage31
- APPEND slxbase=boot/default
- IPAPPEND 3
- */
- $propMap = [
- 'menu label' => ['string', 'title'],
- 'menu default' => ['true', 'isDefault'],
- 'menu hide' => ['true', 'isHidden'],
- 'kernel' => ['string', 'kernel'],
- 'initrd' => ['string', 'initrd'],
- 'append' => ['string', 'append'],
- 'ipappend' => ['int', 'ipAppend'],
- 'localboot' => ['int', 'localBoot'],
- ];
- $sections = array();
- $lines = preg_split('/[\r\n]+/', $input);
- $section = null;
- foreach ($lines as $line) {
- if (!preg_match('/^\s*([^m\s]+|menu\s+\S+)\s+(.*?)\s*$/i', $line, $out))
- continue;
- $key = strtolower($out[1]);
- $key = preg_replace('/\s+/', ' ', $key);
- if ($key === 'label') {
- if ($section !== null) {
- $sections[] = $section;
- }
- $section = new PxeSection($out[2]);
- } elseif ($section === null) {
- continue;
- } elseif (isset($propMap[$key])) {
- $opt = $propMap[$key];
- if ($opt[0] === 'true') {
- $val = true;
- } else {
- $val = $out[2];
- settype($val, $opt[0]);
- }
- $section->{$opt[1]} = $val;
- }
- }
- if ($section !== null) {
- $sections[] = $section;
- }
- return $sections;
- }
-
-}
-
-class PxeMenu
-{
- public $title;
- public $timeoutMs;
- public $totalTimeoutMs;
- public $timeoutLabel;
-}
-
-class PxeSection
-{
- /**
- * @var string label used internally in PXEMENU definition to address this entry
- */
- public $label;
- /**
- * @var string MENU LABEL of PXEMENU - title of entry displayed to the user
- */
- public $title;
- public $kernel;
- public $initrd;
- public $append;
- /**
- * @var int IPAPPEND from PXEMENU. Bitmask of valid options 1 and 2.
- */
- public $ipAppend;
- public $passwd;
- /**
- * @var bool whether this section is marked as default (booted after timeout)
- */
- public $isDefault = false;
- /**
- * @var bool Menu entry is not visible (can only be triggered by timeout)
- */
- public $isHidden = false;
- /**
- * @var int Value of the LOCALBOOT field
- */
- public $localBoot;
-
- public function __construct($label) { $this->label = $label; }
-}
-
diff --git a/modules-available/serversetup-bwlp/lang/de/permissions.json b/modules-available/serversetup-bwlp/lang/de/permissions.json
deleted file mode 100644
index 673bf153..00000000
--- a/modules-available/serversetup-bwlp/lang/de/permissions.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "edit.address": "Boot-Adresse des Servers auswählen.",
- "edit.menu": "Bootmenü anpassen.",
- "download": "USB-Image herunteladen."
-} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/lang/en/permissions.json b/modules-available/serversetup-bwlp/lang/en/permissions.json
deleted file mode 100644
index c04f09f7..00000000
--- a/modules-available/serversetup-bwlp/lang/en/permissions.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "edit.address": "Choose boot address of the server.",
- "edit.menu": "Customize boot menu.",
- "download": "Download USB Image."
-} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/permissions/permissions.json b/modules-available/serversetup-bwlp/permissions/permissions.json
deleted file mode 100644
index 2166cf8e..00000000
--- a/modules-available/serversetup-bwlp/permissions/permissions.json
+++ /dev/null
@@ -1,5 +0,0 @@
-[
- "edit.address",
- "edit.menu",
- "download"
-] \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/style.css b/modules-available/serversetup-bwlp/style.css
deleted file mode 100644
index 3aea98af..00000000
--- a/modules-available/serversetup-bwlp/style.css
+++ /dev/null
@@ -1,12 +0,0 @@
-.disabledPanel {
- cursor: not-allowed;
-}
-
-.disabledPanel > .panel-body {
- pointer-events: none;
- opacity: 0.8;
-}
-
-.panel-footer .btn-group {
- cursor: not-allowed;
-} \ No newline at end of file
diff --git a/modules-available/serversetup-bwlp/templates/ipxe_update.html b/modules-available/serversetup-bwlp/templates/ipxe_update.html
deleted file mode 100644
index 9c598667..00000000
--- a/modules-available/serversetup-bwlp/templates/ipxe_update.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<div class="panel panel-default">
- <div class="panel-heading">{{lang_menuGeneration}}</div>
- <div class="panel-body">
- <div data-tm-id="{{taskid}}" data-tm-log="error" data-tm-callback="restartCb">{{lang_menuGeneration}}</div>
- <div id="genfailed" class="alert alert-danger" style="display:none">
- {{lang_generationFailed}}
- </div>
- </div>
-</div>
-
-<script type="text/javascript">
- function restartCb(task)
- {
- if (!task || !task.statusCode)
- return;
- if (task.statusCode === 'TASK_ERROR') {
- $('#genfailed').show('slow');
- }
- }
-</script>
diff --git a/modules-available/session/config.json b/modules-available/session/config.json
index 2c63c085..0637a088 100644
--- a/modules-available/session/config.json
+++ b/modules-available/session/config.json
@@ -1,2 +1 @@
-{
-}
+[] \ No newline at end of file
diff --git a/modules-available/statistics/api.inc.php b/modules-available/statistics/api.inc.php
index a7a636b3..d4b8f346 100644
--- a/modules-available/statistics/api.inc.php
+++ b/modules-available/statistics/api.inc.php
@@ -34,7 +34,8 @@ if ($type{0} === '~') {
// External mode of operation?
$mode = Request::post('mode', false, 'string');
$NOW = time();
- $old = Database::queryFirst('SELECT clientip, logintime, lastseen, lastboot, state, mbram, cpumodel FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid));
+ $old = Database::queryFirst('SELECT clientip, logintime, lastseen, lastboot, state, mbram, cpumodel, live_memfree, live_swapfree, live_tmpfree
+ FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid));
if ($old !== false) {
settype($old['logintime'], 'integer');
settype($old['lastseen'], 'integer');
@@ -114,6 +115,7 @@ if ($type{0} === '~') {
. ' cpumodel = :cpumodel,'
. ' systemmodel = :systemmodel,'
. ' id44mb = :id44mb,'
+ . ' live_tmpsize = 0, live_swapsize = 0, live_memsize = 0,'
. ' badsectors = :badsectors,'
. ' data = :data,'
. ' state = :state '
@@ -123,32 +125,20 @@ if ($type{0} === '~') {
}
}
// Maybe log old crashed session
- if ($uptime < 120) {
+ if ($uptime < 150 && $old !== false) {
// See if we have a lingering session, create statistic entry if so
- if ($old !== false && $old['logintime'] !== 0) {
+ if ($old['state'] === 'OCCUPIED' && $old['logintime'] !== 0) {
$sessionLength = $old['lastseen'] - $old['logintime'];
if ($sessionLength > 30 && $sessionLength < 86400*2) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:start, '~session-length', :uuid, :clientip, '', :length)", array(
- 'start' => $old['logintime'],
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $sessionLength
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SESSION_LENGTH, $old['logintime'], $sessionLength);
}
}
// Write poweroff period length to statistic table
- if ($old !== false && $old['lastseen'] !== 0) {
+ if ($old['lastseen'] !== 0) {
$lastSeen = $old['lastseen'];
$offtime = ($NOW - $uptime) - $lastSeen;
- if ($offtime > 300 && $offtime < 86400 * 90) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:shutdown, '~offline-length', :uuid, :clientip, '', :length)", array(
- 'shutdown' => $lastSeen,
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $offtime
- ));
+ if ($offtime > 90 && $offtime < 86400 * 30) {
+ Statistics::logMachineState($uuid, $ip, $old['state'] === 'STANDBY' ? Statistics::SUSPEND_LENGTH : Statistics::OFFLINE_LENGTH, $lastSeen, $offtime);
}
}
}
@@ -161,6 +151,14 @@ if ($type{0} === '~') {
// Check for suspicious hardware changes
if ($old !== false) {
checkHardwareChange($old, $new);
+
+ // Log potential crash
+ if ($old['state'] === 'IDLE' || $old['state'] === 'OCCUPIED') {
+ writeClientLog('machine-mismatch-poweron', 'Poweron event, but previous known state is ' . $old['state']
+ . '. RAM: ' . Util::readableFileSize($old['live_memfree'], -1, 2)
+ . ', Swap: ' . Util::readableFileSize($old['live_swapfree'], -1, 2)
+ . ', ID44: ' . Util::readableFileSize($old['live_tmpfree'], -1, 2));
+ }
}
// Write statistics data
@@ -168,36 +166,45 @@ if ($type{0} === '~') {
} else if ($type === '~runstate') {
// Usage (occupied/free)
$sessionLength = 0;
+ $strUpdateBoottime = '';
if ($old === false) die("Unknown machine.\n");
if ($old['clientip'] !== $ip) {
EventLog::warning("[runstate] IP address of client $uuid seems to have changed ({$old['clientip']} -> $ip)");
die("Address changed.\n");
}
$used = Request::post('used', 0, 'integer');
- if ($old['state'] === 'OFFLINE' && $NOW - $old['lastseen'] > 600) {
- $strUpdateBoottime = ' lastboot = UNIX_TIMESTAMP(), ';
- } else {
- $strUpdateBoottime = '';
- }
- // 1) Log last session length if we didn't see the machine for a while
- if ($NOW - $old['lastseen'] > 610 && $old['lastseen'] !== 0) {
- // Old session timed out - might be caused by hard reboot
- if ($old['logintime'] !== 0) {
- if ($old['lastseen'] > $old['logintime']) {
- $sessionLength = $old['lastseen'] - $old['logintime'];
- }
- $old['logintime'] = 0;
- }
- }
- // Figure out what's happening - state changes
$params = array(
'uuid' => $uuid,
'oldlastseen' => $old['lastseen'],
'oldstate' => $old['state'],
);
+ if ($old['state'] === 'OFFLINE') {
+ // This should never happen -- we expect a poweron event before runstate, which would set the state to IDLE
+ // So it might be that the poweron event got lost, or that a couple of runstate events got lost, which
+ // caused our cron.inc.php to time out the client and reset it to OFFLINE
+ if ($NOW - $old['lastseen'] > 900) {
+ $strUpdateBoottime = ' lastboot = UNIX_TIMESTAMP(), ';
+ }
+ // 1) Log last session length if we didn't see the machine for a while
+ if ($NOW - $old['lastseen'] > 900 && $old['lastseen'] !== 0) {
+ // Old session timed out - might be caused by hard reboot
+ if ($old['logintime'] !== 0) {
+ if ($old['lastseen'] > $old['logintime']) {
+ $sessionLength = $old['lastseen'] - $old['logintime'];
+ }
+ }
+ }
+ }
+ foreach (['memsize', 'tmpsize', 'swapsize', 'memfree', 'tmpfree', 'swapfree'] as $item) {
+ $strUpdateBoottime .= ' live_' . $item . ' = :_' . $item . ', ';
+ $params['_' . $item] = ceil(Request::post($item, 0, 'int') / 1024);
+ }
+ // Figure out what's happening - state changes
if ($used === 0 && $old['state'] !== 'IDLE') {
- // Is not in use, was in use before
- $sessionLength = $NOW - $old['logintime'];
+ if ($old['state'] === 'OCCUPIED' && $sessionLength === 0) {
+ // Is not in use, was in use before
+ $sessionLength = $NOW - $old['logintime'];
+ }
$res = Database::exec('UPDATE machine SET lastseen = UNIX_TIMESTAMP(),'
. $strUpdateBoottime
. " logintime = 0, currentuser = NULL, state = 'IDLE' "
@@ -227,13 +234,7 @@ if ($type{0} === '~') {
}
// 9) Log last session length if applicable
if ($mode === false && $sessionLength > 0 && $sessionLength < 86400*2 && $old['logintime'] !== 0) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:start, '~session-length', :uuid, :clientip, '', :length)", array(
- 'start' => $old['logintime'],
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $sessionLength
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SESSION_LENGTH, $old['logintime'], $sessionLength);
}
} elseif ($type === '~poweroff') {
if ($old === false) die("Unknown machine.\n");
@@ -241,16 +242,10 @@ if ($type{0} === '~') {
EventLog::warning("[poweroff] IP address of client $uuid seems to have changed ({$old['clientip']} -> $ip)");
die("Address changed.\n");
}
- if ($mode === false && $old['logintime'] !== 0) {
+ if ($mode === false && $old['state'] === 'OCCUPIED' && $old['logintime'] !== 0) {
$sessionLength = $old['lastseen'] - $old['logintime'];
if ($sessionLength > 0 && $sessionLength < 86400*2) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:start, '~session-length', :uuid, :clientip, '', :length)", array(
- 'start' => $old['logintime'],
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $sessionLength
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SESSION_LENGTH, $old['logintime'], $sessionLength);
}
}
Database::exec("UPDATE machine SET logintime = 0, lastseen = UNIX_TIMESTAMP(), state = 'OFFLINE'
@@ -267,6 +262,10 @@ if ($type{0} === '~') {
foreach ($screens as $port => $screen) {
if (!array_key_exists('name', $screen))
continue;
+ // Filter bogus data
+ $screen['name'] = iconv('UTF-8', 'UTF-8//IGNORE', $screen['name']);
+ if (empty($screen['name']))
+ continue;
if (array_key_exists($screen['name'], $hwids)) {
$hwid = $hwids[$screen['name']];
} else {
@@ -359,13 +358,7 @@ if ($type{0} === '~') {
$lastSeen = $old['lastseen'];
$duration = $NOW - $lastSeen;
if ($duration > 500 && $duration < 86400 * 14) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:suspend, '~suspend-length', :uuid, :clientip, '', :length)", array(
- 'suspend' => $lastSeen,
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $duration
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SUSPEND_LENGTH, $lastSeen, $duration);
}
}
} else {
@@ -399,6 +392,18 @@ function writeStatisticLog($type, $username, $data)
));
}
+function writeClientLog($type, $description)
+{
+ global $ip, $uuid;
+ Database::exec('INSERT INTO clientlog (dateline, logtypeid, clientip, machineuuid, description, extra) VALUES (UNIX_TIMESTAMP(), :type, :client, :uuid, :description, :longdesc)', array(
+ 'type' => $type,
+ 'client' => $ip,
+ 'description' => $description,
+ 'longdesc' => '',
+ 'uuid' => $uuid,
+ ));
+}
+
// For backwards compat, we require the . prefix
if ($type{0} === '.') {
@@ -428,10 +433,16 @@ if ($type{0} === '.') {
function checkHardwareChange($old, $new)
{
if ($new['mbram'] !== 0) {
- if ($new['mbram'] + 1000 < $old['mbram']) {
- $ram1 = round($old['mbram'] / 512) / 2;
- $ram2 = round($new['mbram'] / 512) / 2;
- EventLog::warning('[poweron] Client ' . $new['uuid'] . ' (' . $new['clientip'] . "): RAM decreased from {$ram1}GB to {$ram2}GB");
+ if ($new['mbram'] < 6200) {
+ $ram1 = ceil($old['mbram'] / 512) / 2;
+ $ram2 = ceil($new['mbram'] / 512) / 2;
+ } else {
+ $ram1 = ceil($old['mbram'] / 1024);
+ $ram2 = ceil($new['mbram'] / 1024);
+ }
+ if ($ram1 !== $ram2) {
+ $word = $ram1 > $ram2 ? 'decreased' : 'increased';
+ EventLog::warning('[poweron] Client ' . $new['uuid'] . ' (' . $new['clientip'] . "): RAM $word from {$ram1}GB to {$ram2}GB");
}
if (!empty($old['cpumodel']) && !empty($new['cpumodel']) && $new['cpumodel'] !== $old['cpumodel']) {
EventLog::warning('[poweron] Client ' . $new['uuid'] . ' (' . $new['clientip'] . "): CPU changed from '{$old['cpumodel']}' to '{$new['cpumodel']}'");
diff --git a/modules-available/statistics/config.json b/modules-available/statistics/config.json
index 333f881a..412dc3cb 100644
--- a/modules-available/statistics/config.json
+++ b/modules-available/statistics/config.json
@@ -1,5 +1,9 @@
{
- "category":"main.status",
- "dependencies": [ "js_chart", "js_selectize", "bootstrap_datepicker"],
- "permission":"0"
-}
+ "category": "main.status",
+ "dependencies": [
+ "js_chart",
+ "js_selectize",
+ "bootstrap_datepicker"
+ ],
+ "permission": "0"
+} \ No newline at end of file
diff --git a/modules-available/statistics/hooks/cron.inc.php b/modules-available/statistics/hooks/cron.inc.php
index 4df7b0d4..6393b2c6 100644
--- a/modules-available/statistics/hooks/cron.inc.php
+++ b/modules-available/statistics/hooks/cron.inc.php
@@ -21,9 +21,37 @@ function logstats()
function state_cleanup()
{
// Fix online state of machines that crashed
- $standby = time() - 86400 * 2; // Reset standby machines after two days
+ $standby = time() - 86400 * 4; // Reset standby machines after four days
$on = time() - 610; // Reset others after ~10 minutes
- Database::exec("UPDATE machine SET state = 'OFFLINE' WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
+ // Query for logging
+ $res = Database::simpleQuery("SELECT machineuuid, clientip, state, logintime, lastseen, live_memfree, live_swapfree, live_tmpfree
+ FROM machine WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ Database::exec('INSERT INTO clientlog (dateline, logtypeid, clientip, machineuuid, description, extra)
+ VALUES (UNIX_TIMESTAMP(), :type, :client, :uuid, :description, :longdesc)', array(
+ 'type' => 'machine-mismatch-cron',
+ 'client' => $row['clientip'],
+ 'description' => 'Client timed out, last known state is ' . $row['state']
+ . '. RAM: ' . Util::readableFileSize($row['live_memfree'], -1, 2)
+ . ', Swap: ' . Util::readableFileSize($row['live_swapfree'], -1, 2)
+ . ', ID44: ' . Util::readableFileSize($row['live_tmpfree'], -1, 2),
+ 'longdesc' => '',
+ 'uuid' => $row['machineuuid'],
+ ));
+ if ($row['state'] === 'OCCUPIED') {
+ $length = $row['lastseen'] - $row['logintime'];
+ if ($length > 0 && $length < 86400 * 7) {
+ Statistics::logMachineState($row['machineuuid'], $row['clientip'], Statistics::SESSION_LENGTH, $row['logintime'], $length);
+ }
+ } elseif ($row['state'] === 'STANDBY') {
+ $length = time() - $row['lastseen'];
+ if ($length > 0 && $length < 86400 * 7) {
+ Statistics::logMachineState($row['machineuuid'], $row['clientip'], Statistics::SUSPEND_LENGTH, $row['lastseen'], $length);
+ }
+ }
+ }
+ // Update -- yes this is not atomic. Should be sufficient for simple warnings and bookkeeping though.
+ Database::exec("UPDATE machine SET logintime = 0, state = 'OFFLINE' WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
}
state_cleanup();
diff --git a/modules-available/statistics/inc/filter.inc.php b/modules-available/statistics/inc/filter.inc.php
index f6765059..46de467b 100644
--- a/modules-available/statistics/inc/filter.inc.php
+++ b/modules-available/statistics/inc/filter.inc.php
@@ -14,18 +14,24 @@ class Filter
public $operator;
public $argument;
+ private static $keyCounter = 0;
+
+ public static function getNewKey($colname)
+ {
+ return $colname . '_' . (self::$keyCounter++);
+ }
+
public function __construct($column, $operator, $argument = null)
{
$this->column = trim($column);
$this->operator = trim($operator);
- $this->argument = trim($argument);
+ $this->argument = is_array($argument) ? $argument : trim($argument);
}
/* returns a where clause and adds needed operators to the passed array */
public function whereClause(&$args, &$joins)
{
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
$addendum = '';
/* check if we have to do some parsing*/
@@ -187,20 +193,24 @@ class Id44Filter extends Filter
public function whereClause(&$args, &$joins)
{
global $SIZE_ID44;
- $lower = floor(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, false) * 1024 - 100);
- $upper = ceil(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, true) * 1024 + 100);
+ if ($this->operator === '=' || $this->operator === '!=') {
+ $lower = floor(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, false) * 1024 - 100);
+ $upper = ceil(Page_Statistics::findBestValue($SIZE_ID44, $this->argument, true) * 1024 + 100);
+ } else {
+ $lower = $upper = round($this->argument * 1024);
+ }
- if ($this->operator == '=') {
+ if ($this->operator === '=') {
return " id44mb BETWEEN $lower AND $upper";
- } elseif ($this->operator == '!=') {
+ } elseif ($this->operator === '!=') {
return " id44mb < $lower OR id44mb > $upper";
- } elseif ($this->operator == '<=') {
- return " id44mb < $upper";
- } elseif ($this->operator == '>=') {
- return " id44mb > $lower";
- } elseif ($this->operator == '<') {
+ } elseif ($this->operator === '<=') {
+ return " id44mb <= $upper";
+ } elseif ($this->operator === '>=') {
+ return " id44mb >= $lower";
+ } elseif ($this->operator === '<') {
return " id44mb < $lower";
- } elseif ($this->operator == '>') {
+ } elseif ($this->operator === '>') {
return " id44mb > $upper";
} else {
error_log("unimplemented operator in Id44Filter: $this->operator");
@@ -222,8 +232,7 @@ class StateFilter extends Filter
$map = [ 'on' => ['IDLE', 'OCCUPIED'], 'off' => ['OFFLINE'], 'idle' => ['IDLE'], 'occupied' => ['OCCUPIED'], 'standby' => ['STANDBY'] ];
$neg = $this->operator == '!=' ? 'NOT ' : '';
if (array_key_exists($this->argument, $map)) {
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
$args[$key] = $map[$this->argument];
return " machine.state $neg IN ( :$key ) ";
} else {
@@ -245,13 +254,17 @@ class LocationFilter extends Filter
$recursive = (substr($this->operator, -1) === '~');
$this->operator = str_replace('~', '=', $this->operator);
- settype($this->argument, 'int');
+ if (is_array($this->argument)) {
+ if ($recursive)
+ Util::traceError('Cannot use ~ operator for location with array');
+ } else {
+ settype($this->argument, 'int');
+ }
$neg = $this->operator === '=' ? '' : 'NOT';
if ($this->argument === 0) {
return "machine.locationid IS $neg NULL";
} else {
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
if ($recursive) {
$args[$key] = array_keys(Location::getRecursiveFlat($this->argument));
} else {
diff --git a/modules-available/statistics/inc/filterset.inc.php b/modules-available/statistics/inc/filterset.inc.php
index 25c5c8fa..774bfd18 100644
--- a/modules-available/statistics/inc/filterset.inc.php
+++ b/modules-available/statistics/inc/filterset.inc.php
@@ -9,6 +9,8 @@ class FilterSet
private $sortDirection;
private $sortColumn;
+ private $cache = false;
+
public function __construct($filters)
{
$this->filters = $filters;
@@ -16,19 +18,28 @@ class FilterSet
public function setSort($col, $direction)
{
- $this->sortDirection = $direction === 'DESC' ? 'DESC' : 'ASC';
+ $direction = ($direction === 'DESC' ? 'DESC' : 'ASC');
- if (is_string($col) && array_key_exists($col, Page_Statistics::$columns)) {
- $this->sortColumn = $col;
- } else {
+ if (!is_string($col) || !array_key_exists($col, Page_Statistics::$columns)) {
/* default sorting column is clientip */
- $this->sortColumn = 'clientip';
+ $col = 'clientip';
}
-
+ if ($col === $this->sortColumn && $direction === $this->sortDirection)
+ return;
+ $this->cache = false;
+ $this->sortDirection = $direction;
+ $this->sortColumn = $col;
}
public function makeFragments(&$where, &$join, &$sort, &$args)
{
+ if ($this->cache !== false) {
+ $where = $this->cache['where'];
+ $join = $this->cache['join'];
+ $sort = $this->cache['sort'];
+ $args = $this->cache['args'];
+ return;
+ }
/* generate where clause & arguments */
$where = '';
$joins = [];
@@ -54,16 +65,13 @@ class FilterSet
$sort = " ORDER BY " . $concreteCol . " " . $this->sortDirection
. ", machineuuid ASC";
+ $this->cache = compact('where', 'join', 'sort', 'args');
}
public function isNoId44Filter()
{
- foreach ($this->filters as $filter) {
- if (get_class($filter) === 'Id44Filter' && $filter->argument == 0) {
- return true;
- }
- }
- return false;
+ $filter = $this->hasFilter('Id44Filter');
+ return $filter !== false && $filter->argument == 0;
}
public function getSortDirection()
@@ -78,10 +86,58 @@ class FilterSet
public function filterNonClients()
{
- if (Module::get('runmode') === false)
+ if (Module::get('runmode') === false || $this->hasFilter('IsClientFilter') !== false)
return;
+ $this->cache = false;
// Runmode module exists, add filter
$this->filters[] = new IsClientFilter(true);
}
+ /**
+ * @param string $type filter type (class name)
+ * @return false|Filter The filter, false if not found
+ */
+ public function hasFilter($type)
+ {
+ foreach ($this->filters as $filter) {
+ if (get_class($filter) === $type) {
+ return $filter;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add a location filter based on the allowed permissions for the given permission.
+ * Returns false if the user doesn't have the given permission for any location.
+ *
+ * @param string $permission permission to use
+ * @return bool false if no permission for any location, true otherwise
+ */
+ public function setAllowedLocationsFromPermission($permission)
+ {
+ $locs = User::getAllowedLocations($permission);
+ if (empty($locs))
+ return false;
+ if (in_array(0, $locs)) {
+ if (!isset($this->filters['permissions']))
+ return true;
+ unset($this->filters['permissions']);
+ } else {
+ $this->filters['permissions'] = new LocationFilter('=', $locs);
+ }
+ $this->cache = false;
+ return true;
+ }
+
+ /**
+ * @return false|array
+ */
+ public function getAllowedLocations()
+ {
+ if (isset($this->filters['permissions']->argument) && is_array($this->filters['permissions']->argument))
+ return $this->filters['permissions']->argument;
+ return false;
+ }
+
}
diff --git a/modules-available/statistics/inc/parser.inc.php b/modules-available/statistics/inc/parser.inc.php
index 679055a7..0d39079d 100644
--- a/modules-available/statistics/inc/parser.inc.php
+++ b/modules-available/statistics/inc/parser.inc.php
@@ -104,10 +104,12 @@ class Parser {
foreach ($lines as $line) {
if (preg_match('/^Disk (\S+):.* (\d+) bytes/i', $line, $out)) {
// --- Beginning of MBR disk ---
+ unset($hdd);
if ($out[2] < 10000) // sometimes vmware reports lots of 512byte disks
continue;
+ if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper
+ continue;
// disk total size and name
- unset($hdd);
$mbrToMbFactor = 0; // This is != 0 for mbr
$sectorToMbFactor = 0; // This is != for gpt
$hdd = array(
@@ -122,10 +124,12 @@ class Parser {
$hdds[] = &$hdd;
} elseif (preg_match('/^Disk (\S+):\s+(\d+)\s+sectors,/i', $line, $out)) {
// --- Beginning of GPT disk ---
+ unset($hdd);
if ($out[2] < 1000) // sometimes vmware reports lots of 512byte disks
continue;
+ if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper
+ continue;
// disk total size and name
- unset($hdd);
$mbrToMbFactor = 0; // This is != 0 for mbr
$sectorToMbFactor = 0; // This is != for gpt
$hdd = array(
@@ -151,24 +155,44 @@ class Parser {
$type = strtolower($out[4]);
if ($type === '5' || $type === 'f' || $type === '85') {
continue;
+ } elseif ($type === '44') {
+ $out[5] = 'OpenSLX-ID44';
+ $color = '#5c1';
+ } elseif ($type === '45') {
+ $out[5] = 'OpenSLX-ID45';
+ $color = '#0d7';
+ } elseif ($type === '82') {
+ $color = '#48f';
+ } else {
+ $color = '#e55';
}
+
$partsize = round(($out[3] - $out[2]) * $mbrToMbFactor);
$hdd['partitions'][] = array(
'id' => $out[1],
'name' => $out[1],
'size' => round($partsize / 1024, $partsize < 1024 ? 1 : 0),
- 'type' => ($type === '44' ? 'OpenSLX' : $out[5]),
+ 'type' => $out[5],
);
$hdd['json'][] = array(
'label' => $out[1],
'value' => $partsize,
- 'color' => ($type === '44' ? '#4d4' : ($type === '82' ? '#48f' : '#e55')),
+ 'color' => $color,
);
$hdd['used'] += $partsize;
} elseif (isset($hdd) && $sectorToMbFactor !== 0 && preg_match(',^\s*(\d+)\s+(\d+)[\+\-]?\s+(\d+)[\+\-]?\s+\S+\s+([0-9a-f]+)\s+(.*)$,i', $line, $out)) {
// --- GPT: Partition entry ---
// Some partition
$type = $out[5];
+ if ($type === 'OpenSLX-ID44') {
+ $color = '#5c1';
+ } elseif ($type === 'OpenSLX-ID45') {
+ $color = '#0d7';
+ } elseif ($type === 'Linux swap') {
+ $color = '#48f';
+ } else {
+ $color = '#e55';
+ }
$id = $hdd['devid'] . '-' . $out[1];
$partsize = round(($out[3] - $out[2]) * $sectorToMbFactor);
$hdd['partitions'][] = array(
@@ -180,7 +204,7 @@ class Parser {
$hdd['json'][] = array(
'label' => $id,
'value' => $partsize,
- 'color' => ($type === 'OpenSLX-ID44' ? '#4d4' : ($type === 'Linux swap' ? '#48f' : '#e55')),
+ 'color' => $color,
);
$hdd['used'] += $partsize;
}
@@ -193,7 +217,7 @@ class Parser {
$hdd['size'] = round(($hdd['sectors'] * $sectorToMbFactor) / 1024);
}
$free = $hdd['size'] - $hdd['used'];
- if ($free > 5 || ($free / $hdd['size']) > 0.1) {
+ if ($hdd['size'] > 0 && ($free > 5 || ($free / $hdd['size']) > 0.1)) {
$hdd['partitions'][] = array(
'id' => 'free-id-' . $i,
'name' => Dictionary::translate('unused'),
diff --git a/modules-available/statistics/inc/statistics.inc.php b/modules-available/statistics/inc/statistics.inc.php
index 2500f16f..1f8a081a 100644
--- a/modules-available/statistics/inc/statistics.inc.php
+++ b/modules-available/statistics/inc/statistics.inc.php
@@ -70,4 +70,21 @@ class Statistics
return $list;
}
+ const SESSION_LENGTH = '~session-length';
+ const OFFLINE_LENGTH = '~offline-length';
+ const SUSPEND_LENGTH = '~suspend-length';
+
+ public static function logMachineState($uuid, $ip, $type, $start, $length, $username = '')
+ {
+ return Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
+ . " VALUES (:start, :type, :uuid, :clientip, :username, :length)", array(
+ 'start' => $start,
+ 'type' => $type,
+ 'uuid' => $uuid,
+ 'clientip' => $ip,
+ 'username' => $username,
+ 'length' => $length,
+ ));
+ }
+
}
diff --git a/modules-available/statistics/install.inc.php b/modules-available/statistics/install.inc.php
index 4e2dfcca..84e038a4 100644
--- a/modules-available/statistics/install.inc.php
+++ b/modules-available/statistics/install.inc.php
@@ -234,5 +234,22 @@ if (!tableHasColumn('machine', 'state')) {
$res[] = UPDATE_DONE;
}
+// 2019-01-25: Add memory/temp stats column
+if (!tableHasColumn('machine', 'live_tmpsize')) {
+ $ret = Database::exec("ALTER TABLE `machine`
+ ADD COLUMN `live_tmpsize` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `id44mb`,
+ ADD COLUMN `live_tmpfree` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_tmpsize`,
+ ADD COLUMN `live_swapsize` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_tmpfree`,
+ ADD COLUMN `live_swapfree` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_swapsize`,
+ ADD COLUMN `live_memsize` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_swapfree`,
+ ADD COLUMN `live_memfree` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_memsize`,
+ ADD INDEX `live_tmpfree` (`live_tmpfree`),
+ ADD INDEX `live_memfree` (`live_memfree`)");
+ if ($ret === false) {
+ finalResponse(UPDATE_FAILED, 'Adding state column to machine table failed: ' . Database::lastError());
+ }
+ $res[] = UPDATE_DONE;
+}
+
// Create response
responseFromArray($res);
diff --git a/modules-available/statistics/lang/de/permissions.json b/modules-available/statistics/lang/de/permissions.json
index 15303993..8579b28f 100644
--- a/modules-available/statistics/lang/de/permissions.json
+++ b/modules-available/statistics/lang/de/permissions.json
@@ -1,5 +1,12 @@
{
- "view": "Client Statistiken anschauen.",
- "note": "Client Notizen speichern.",
- "delete": "Client löschen."
+ "hardware.projectors.edit": "Beamerzuweisung bearbeiten",
+ "hardware.projectors.view": "Beamerzuweisung anzeigen",
+ "machine.delete": "Rechner l\u00f6schen.",
+ "machine.note": "Anmerkungen zu einem Rechner speichern.",
+ "machine.note.edit": "Anmerkungen bearbeiten",
+ "machine.note.view": "Anmerkungen anzeigen",
+ "machine.view-details": "Clientinformationen anzeigen",
+ "view": "Statistiken anschauen.",
+ "view.list": "Clientliste anzeigen",
+ "view.summary": "Visualisierung anzeigen"
} \ No newline at end of file
diff --git a/modules-available/statistics/lang/de/template-tags.json b/modules-available/statistics/lang/de/template-tags.json
index 84c4690c..2567eea1 100644
--- a/modules-available/statistics/lang/de/template-tags.json
+++ b/modules-available/statistics/lang/de/template-tags.json
@@ -14,6 +14,7 @@
"lang_event": "Ereignis",
"lang_eventType": "Typ",
"lang_firstSeen": "Erste Aktivit\u00e4t",
+ "lang_free": "frei",
"lang_gbRam": "RAM",
"lang_hardwareSummary": "Hardware",
"lang_hdds": "Festplatten",
@@ -40,6 +41,7 @@
"lang_machineStandby": "Im Standby",
"lang_machineSummary": "Zusammenfassung",
"lang_maximumAbbrev": "Max.",
+ "lang_memFree": "RAM frei (MB)",
"lang_memoryStats": "Arbeitsspeicher",
"lang_model": "Modell",
"lang_modelCount": "Anzahl",
@@ -82,10 +84,12 @@
"lang_subnet": "Subnetz",
"lang_sureDeletePermanent": "M\u00f6chten Sie diese(n) Rechner wirklich unwiderruflich aus der Datenbank entfernen?\r\n\r\nWichtig: L\u00f6schen verhindert nicht, dass ein Rechner nach erneutem Starten von bwLehrpool wieder in die Datenbank aufgenommen wird.",
"lang_sureReplaceNoUndo": "Wollen Sie die Daten ausgew\u00e4hlten Rechner \u00fcbertragen? Diese Aktion kann nicht r\u00fcckg\u00e4ngig gemacht werden.",
+ "lang_swapFree": "swap frei (MB)",
"lang_tempPart": "Temp. Partition",
"lang_tempPartStats": "Tempor\u00e4re Partition",
"lang_thoseAreProjectors": "Diese Modellnamen werden als Beamer behandelt, auch wenn die EDID-Informationen des Ger\u00e4tes anderes berichten.",
"lang_timebarDesc": "Visuelle Darstellung der letzten Tage. Rote Abschnitte zeigen, wann der Rechner belegt war, gr\u00fcne, wann er nicht verwendet wurde, aber eingeschaltet war. Die leicht abgedunkelten Abschnitte markieren N\u00e4chte (22 bis 8 Uhr).",
+ "lang_tmpFree": "ID44 frei (MB)",
"lang_tmpGb": "Temp-HDD",
"lang_total": "Gesamt",
"lang_usageDetails": "Nutzungsdetails",
diff --git a/modules-available/statistics/lang/en/permissions.json b/modules-available/statistics/lang/en/permissions.json
index 7be32f22..445f96b8 100644
--- a/modules-available/statistics/lang/en/permissions.json
+++ b/modules-available/statistics/lang/en/permissions.json
@@ -1,5 +1,12 @@
{
- "view": "View client statistics.",
- "note": "Save client notes.",
- "delete": "Delete client."
+ "hardware.projectors.edit": "Edit beamer assignment",
+ "hardware.projectors.view": "Show beamer assignment",
+ "machine.delete": "Delete clients.",
+ "machine.note": "Save client notes.",
+ "machine.note.edit": "Edit notes",
+ "machine.note.view": "Show notes",
+ "machine.view-details": "Show client details",
+ "view": "View statistics.",
+ "view.list": "Show client list",
+ "view.summary": "Show visualization"
} \ No newline at end of file
diff --git a/modules-available/statistics/lang/en/template-tags.json b/modules-available/statistics/lang/en/template-tags.json
index b064ee50..1d9cd4da 100644
--- a/modules-available/statistics/lang/en/template-tags.json
+++ b/modules-available/statistics/lang/en/template-tags.json
@@ -14,6 +14,7 @@
"lang_event": "Event",
"lang_eventType": "Type",
"lang_firstSeen": "First seen",
+ "lang_free": "free",
"lang_gbRam": "RAM",
"lang_hardwareSummary": "Hardware",
"lang_hdds": "Hard disk drives",
@@ -40,6 +41,7 @@
"lang_machineStandby": "In standby mode",
"lang_machineSummary": "Summary",
"lang_maximumAbbrev": "max.",
+ "lang_memFree": "RAM free (MB)",
"lang_memoryStats": "Memory",
"lang_model": "Model",
"lang_modelCount": "Count",
@@ -82,10 +84,12 @@
"lang_subnet": "Subnet",
"lang_sureDeletePermanent": "Are your sure you want to delete the selected machine(s) from the database? This cannot be undone.\r\n\r\nNote: Deleting machines from the database does not prevent booting up bwLehrpool again, which would recreate their respective database entries.",
"lang_sureReplaceNoUndo": "Are you sure you want to replace the selected machine pairs? This action cannot be undone.",
+ "lang_swapFree": "swap free (MB)",
"lang_tempPart": "Temp. partition",
"lang_tempPartStats": "Temporary partition",
"lang_thoseAreProjectors": "These model names will always be treated as beamers, even if the device's EDID data says otherwise.",
"lang_timebarDesc": "Visual representation of the last few days. Red parts mark periods where the client was occupied, green parts where the client was idle. Dimmed parts mark nights (10pm to 8am).",
+ "lang_tmpFree": "ID44 free (MB)",
"lang_tmpGb": "Temp HDD",
"lang_total": "Total",
"lang_usageDetails": "Detailed usage",
diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php
index 5fe4ebfa..a9cde6fb 100644
--- a/modules-available/statistics/page.inc.php
+++ b/modules-available/statistics/page.inc.php
@@ -1,165 +1,177 @@
<?php
global $STATS_COLORS, $SIZE_ID44, $SIZE_RAM;
-global $unique_key;
$STATS_COLORS = array();
for ($i = 0; $i < 10; ++$i) {
$STATS_COLORS[] = '#55' . sprintf('%02s%02s', dechex((($i + 1) * ($i + 1)) / .3922), dechex(abs((5 - $i) * 51)));
}
//$STATS_COLORS = array('#57e', '#ee8', '#5ae', '#fb7', '#6d7', '#e77', '#3af', '#666', '#e0e', '#999');
-$SIZE_ID44 = array(0, 8, 16, 24, 30, 40, 50, 60, 80, 100, 120, 150, 180, 250, 300, 350, 400, 450, 500);
+$SIZE_ID44 = array(0, 8, 16, 24, 30, 40, 50, 60, 80, 100, 120, 150, 180, 250, 300, 400, 500, 1000, 2000, 4000);
$SIZE_RAM = array(1, 2, 3, 4, 6, 8, 10, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 320, 480, 512, 768, 1024);
class Page_Statistics extends Page
{
/* some constants, TODO: Find a better place */
- public static $op_nominal;
- public static $op_ordinal;
- public static $op_stringcmp;
+ const OP_NOMINAL = ['!=', '='];
+ const OP_ORDINAL = ['!=', '<=', '>=', '=', '<', '>'];
+ const OP_STRCMP = ['!~', '~', '=', '!='];
public static $columns;
private $query;
-
- private $locationsAllowedToView;
+ private $show;
/**
* @var bool whether we have a SubPage from the pages/ subdir
*/
private $haveSubpage;
- /* PHP sucks, no static, const array definitions... Or am I missing something? */
- public function initConstants()
+ /**
+ * Do this here instead of const since we need to check for available modules while building array.
+ */
+ public static function initConstants()
{
- Page_Statistics::$op_nominal = ['!=', '='];
- Page_Statistics::$op_ordinal = ['!=', '<=', '>=', '=', '<', '>'];
- Page_Statistics::$op_stringcmp = ['!~', '~', '=', '!='];
Page_Statistics::$columns = [
'machineuuid' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true,
],
'macaddr' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true,
],
'firstseen' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'date',
'column' => true,
],
'lastseen' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'date',
'column' => true,
],
'logintime' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'date',
'column' => true,
],
'realcores' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => true,
],
'systemmodel' => [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'string',
'column' => true,
],
'cpumodel' => [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'string',
'column' => true,
],
'hddgb' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => false,
'map_sort' => 'id44mb'
],
'gbram' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'map_sort' => 'mbram',
'column' => false,
],
'kvmstate' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'enum',
'column' => true,
'values' => ['ENABLED', 'DISABLED', 'UNSUPPORTED']
],
'badsectors' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => true
],
'clientip' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true
],
'hostname' => [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'string',
'column' => true
],
'subnet' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => false
],
'currentuser' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true
],
'state' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'enum',
'column' => true,
'values' => ['occupied', 'on', 'off', 'idle', 'standby']
],
- 'runtime' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'live_swapfree' => [
+ 'op' => Page_Statistics::OP_ORDINAL,
+ 'type' => 'int',
+ 'column' => true
+ ],
+ 'live_memfree' => [
+ 'op' => Page_Statistics::OP_ORDINAL,
+ 'type' => 'int',
+ 'column' => true
+ ],
+ 'live_tmpfree' => [
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => true
],
];
if (Module::isAvailable('locations')) {
Page_Statistics::$columns['location'] = [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'enum',
'column' => false,
'values' => array_keys(Location::getLocationsAssoc()),
];
}
- /* TODO ... */
}
protected function doPreprocess()
{
- $this->initConstants();
User::load();
if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
- $this->locationsAllowedToView = User::getAllowedLocations("view");
-
-
- $show = Request::any('show', 'stat', 'string');
- $show = preg_replace('/[^a-z0-9_\-]/', '', $show);
+ $this->show = Request::any('show', false, 'string');
+ if ($this->show === false) {
+ if (User::hasPermission('view.summary')) {
+ $this->show = 'summary';
+ } elseif (User::hasPermission('view.list')) {
+ $this->show = 'list';
+ } else {
+ User::assertPermission('view.summary');
+ }
+ } else {
+ $this->show = preg_replace('/[^a-z0-9_\-]/', '', $this->show);
+ }
- if (file_exists('modules/statistics/pages/' . $show . '.inc.php')) {
+ if (file_exists('modules/statistics/pages/' . $this->show . '.inc.php')) {
- require_once 'modules/statistics/pages/' . $show . '.inc.php';
+ require_once 'modules/statistics/pages/' . $this->show . '.inc.php';
$this->haveSubpage = true;
SubPage::doPreprocess();
@@ -168,20 +180,23 @@ class Page_Statistics extends Page
$action = Request::post('action');
if ($action === 'setnotes') {
$uuid = Request::post('uuid', '', 'string');
- $locationid = Database::queryFirst('SELECT locationid FROM machine WHERE machineuuid = :uuid',
- array('uuid' => $uuid))['locationid'];
- if (User::hasPermission("note", $locationid)) {
- $text = Request::post('content', '', 'string');
- if (empty($text)) {
- $text = null;
- }
- Database::exec('UPDATE machine SET notes = :text WHERE machineuuid = :uuid', array(
- 'uuid' => $uuid,
- 'text' => $text,
- ));
- Message::addSuccess('notes-saved');
- Util::redirect('?do=Statistics&uuid=' . $uuid);
+ $res = Database::queryFirst('SELECT locationid FROM machine WHERE machineuuid = :uuid',
+ array('uuid' => $uuid));
+ if ($res === false) {
+ Message::addError('unknown-machine', $uuid);
+ Util::redirect('?do=statistics');
}
+ User::assertPermission("machine.note.edit", (int)$res['locationid']);
+ $text = Request::post('content', null, 'string');
+ if (empty($text)) {
+ $text = null;
+ }
+ Database::exec('UPDATE machine SET notes = :text WHERE machineuuid = :uuid', array(
+ 'uuid' => $uuid,
+ 'text' => $text,
+ ));
+ Message::addSuccess('notes-saved');
+ Util::redirect('?do=statistics&uuid=' . $uuid);
} elseif ($action === 'delmachines') {
$this->deleteMachines();
Util::redirect('?do=statistics', true);
@@ -204,14 +219,20 @@ class Page_Statistics extends Page
Message::addError('main.parameter-empty', 'uuid');
return;
}
+ $allowedLocations = User::getAllowedLocations("machine.delete");
+ if (empty($allowedLocations)) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=statistics');
+ }
$res = Database::simpleQuery('SELECT machineuuid, locationid FROM machine WHERE machineuuid IN (:ids)', compact('ids'));
$ids = array_flip($ids);
$delete = [];
- $allowedLocations = User::getAllowedLocations("delete");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ unset($ids[$row['machineuuid']]);
if (in_array($row['locationid'], $allowedLocations)) {
- unset($ids[$row['machineuuid']]);
$delete[] = $row['machineuuid'];
+ } else {
+ Message::addError('locations.no-permission-location', $row['locationid']);
}
}
if (!empty($delete)) {
@@ -219,7 +240,6 @@ class Page_Statistics extends Page
Message::addSuccess('deleted-n-machines', count($delete));
}
if (!empty($ids)) {
- // TODO: Warn permissions
Message::addWarning('unknown-machine', implode(', ', array_keys($ids)));
}
}
@@ -237,8 +257,6 @@ class Page_Statistics extends Page
return;
}
- $show = Request::get('show', 'stat', 'string');
-
/* read filter */
$this->query = Request::any('filters', false);
if ($this->query === false) {
@@ -251,23 +269,31 @@ class Page_Statistics extends Page
$filterSet = new FilterSet($filters);
$filterSet->setSort($sortColumn, $sortDirection);
- if ($show == 'list') {
+ if (!$filterSet->setAllowedLocationsFromPermission('view.' . $this->show)) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=main');
+ }
+
+ if ($this->show === 'list') {
Render::openTag('div', array('class' => 'row'));
$this->showFilter('list', $filterSet);
Render::closeTag('div');
$this->showMachineList($filterSet);
return;
+ } elseif ($this->show === 'summary') {
+ $filterSet->filterNonClients();
+ Render::openTag('div', array('class' => 'row'));
+ $this->showFilter('summary', $filterSet);
+ $this->showSummary($filterSet);
+ $this->showMemory($filterSet);
+ $this->showId44($filterSet);
+ $this->showKvmState($filterSet);
+ $this->showLatestMachines($filterSet);
+ $this->showSystemModels($filterSet);
+ Render::closeTag('div');
+ } else {
+ Message::addError('main.value-invalid', 'show', $this->show);
}
- $filterSet->filterNonClients();
- Render::openTag('div', array('class' => 'row'));
- $this->showFilter('stat', $filterSet);
- $this->showSummary($filterSet);
- $this->showMemory($filterSet);
- $this->showId44($filterSet);
- $this->showKvmState($filterSet);
- $this->showLatestMachines($filterSet);
- $this->showSystemModels($filterSet);
- Render::closeTag('div');
}
/**
@@ -295,15 +321,17 @@ class Page_Statistics extends Page
$locsFlat = array();
if (Module::isAvailable('locations')) {
+ $allowed = $filterSet->getAllowedLocations();
foreach (Location::getLocations() as $loc) {
$locsFlat['L' . $loc['locationid']] = array(
'pad' => $loc['locationpad'],
'name' => $loc['locationname'],
- 'disabled' => !in_array($loc['locationid'], $this->locationsAllowedToView)
+ 'disabled' => $allowed !== false && !in_array($loc['locationid'], $allowed),
);
}
}
+ Permission::addGlobalTags($data['perms'], null, ['view.summary', 'view.list']);
$data['locations'] = json_encode($locsFlat);
Render::addTemplate('filterbox', $data);
@@ -355,8 +383,6 @@ class Page_Statistics extends Page
private function showSummary($filterSet)
{
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$known = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE $where", $args);
// If we only have one machine, redirect to machine details
if ($known['val'] == 1) {
@@ -417,8 +443,6 @@ class Page_Statistics extends Page
global $STATS_COLORS;
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$res = Database::simpleQuery('SELECT systemmodel, Round(AVG(realcores)) AS cores, Count(*) AS `count` FROM machine'
. " $join WHERE $where GROUP BY systemmodel ORDER BY `count` DESC, systemmodel ASC", $args);
$lines = array();
@@ -451,8 +475,6 @@ class Page_Statistics extends Page
global $STATS_COLORS, $SIZE_RAM;
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$res = Database::simpleQuery("SELECT mbram, Count(*) AS `count` FROM machine $join WHERE $where GROUP BY mbram", $args);
$lines = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
@@ -498,8 +520,6 @@ class Page_Statistics extends Page
private function showKvmState($filterSet)
{
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$colors = array('UNKNOWN' => '#666', 'UNSUPPORTED' => '#ea5', 'DISABLED' => '#e55', 'ENABLED' => '#6d6');
$res = Database::simpleQuery("SELECT kvmstate, Count(*) AS `count` FROM machine $join WHERE $where GROUP BY kvmstate ORDER BY `count` DESC", $args);
$lines = array();
@@ -523,8 +543,6 @@ class Page_Statistics extends Page
global $STATS_COLORS, $SIZE_ID44;
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$res = Database::simpleQuery("SELECT id44mb, Count(*) AS `count` FROM machine $join WHERE $where GROUP BY id44mb", $args);
$lines = array();
$total = 0;
@@ -576,8 +594,6 @@ class Page_Statistics extends Page
private function showLatestMachines($filterSet)
{
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$args['cutoff'] = ceil(time() / 3600) * 3600 - 86400 * 10;
$res = Database::simpleQuery("SELECT machineuuid, clientip, hostname, firstseen, mbram, kvmstate, id44mb FROM machine $join"
@@ -611,8 +627,6 @@ class Page_Statistics extends Page
{
Module::isAvailable('js_stupidtable');
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$xtra = '';
if ($filterSet->isNoId44Filter()) {
$xtra .= ', data';
@@ -629,14 +643,17 @@ class Page_Statistics extends Page
. " $join WHERE $where $sort", $args);
$rows = array();
$singleMachine = 'none';
- $deleteAllowedLocations = User::getAllowedLocations("delete");
+ $deleteAllowedLocations = User::getAllowedLocations("machine.delete");
+ $detailsAllowedLocations = User::getAllowedLocations("machine.view-details");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
if ($singleMachine === 'none') {
$singleMachine = $row['machineuuid'];
} else {
$singleMachine = false;
}
- $row['deleteAllowed'] = in_array($row['locationid'], $deleteAllowedLocations);
+ // TODO: This only makes sense as long as there is only one action to perform on selected clients; reboot/shutdown is planned
+ $row['delete_disabled'] = in_array($row['locationid'], $deleteAllowedLocations) ? '' : 'disabled';
+ $row['link_details'] = in_array($row['locationid'], $detailsAllowedLocations);
$row['state_' . $row['state']] = true;
//$row['firstseen'] = Util::prettyTime($row['firstseen']);
$row['lastseen_int'] = $row['lastseen'];
@@ -668,12 +685,13 @@ class Page_Statistics extends Page
$row['modeName'] = $data['modeName'];
}
}
+ $row['locationname'] = Location::getName($row['locationid']);
$rows[] = $row;
}
if ($singleMachine !== false && $singleMachine !== 'none') {
Util::redirect('?do=statistics&uuid=' . $singleMachine);
}
- Render::addTemplate('clientlist', array(
+ $data = array(
'rowCount' => count($rows),
'rows' => $rows,
'query' => $this->query,
@@ -684,7 +702,8 @@ class Page_Statistics extends Page
'showList' => 1,
'show' => 'list',
'redirect' => $_SERVER['QUERY_STRING']
- ));
+ );
+ Render::addTemplate('clientlist', $data);
}
private function ramColorClass($mb)
@@ -755,9 +774,9 @@ class Page_Statistics extends Page
$row['currentsession'] = $lecture['displayname'];
$row['lectureid'] = $lecture['lectureid'];
}
+ $row['session'] = $row['currentsession'];
+ return;
}
- $row['session'] = $row['currentsession'];
- return;
}
$res = Database::simpleQuery('SELECT dateline, username, data FROM statistic'
. " WHERE clientip = :ip AND typeid = '.vmchooser-session-name'"
@@ -774,23 +793,23 @@ class Page_Statistics extends Page
}
if ($session !== false) {
$row['session'] = $session['data'];
- $row['username'] = $session['username'];
+ if (empty($row['currentuser'])) {
+ $row['username'] = $session['username'];
+ }
}
}
private function showMachine($uuid)
{
- $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot, state,'
- . ' mbram, kvmstate, cpumodel, id44mb, data, hostname, currentuser, currentsession, notes FROM machine WHERE machineuuid = :uuid',
+ $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot, state,
+ mbram, live_tmpsize, live_tmpfree, live_swapsize, live_swapfree, live_memsize, live_memfree,
+ kvmstate, cpumodel, id44mb, data, hostname, currentuser, currentsession, notes FROM machine WHERE machineuuid = :uuid',
array('uuid' => $uuid));
if ($client === false) {
Message::addError('unknown-machine', $uuid);
return;
}
- if (!in_array($client['locationid'], $this->locationsAllowedToView)) {
- Message::addError('main.no-permission');
- return;
- }
+ User::assertPermission('machine.view-details', (int)$client['locationid']);
// Hack: Get raw collected data
if (Request::get('raw', false)) {
Header('Content-Type: text/plain; charset=utf-8');
@@ -820,6 +839,7 @@ class Page_Statistics extends Page
$client['state_' . $client['state']] = true;
$client['firstseen_s'] = date('d.m.Y H:i', $client['firstseen']);
$client['lastseen_s'] = date('d.m.Y H:i', $client['lastseen']);
+ $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']);
if ($client['lastboot'] == 0) {
$client['lastboot_s'] = '-';
} else {
@@ -829,9 +849,14 @@ class Page_Statistics extends Page
$client['lastboot_s'] .= ' (Up ' . floor($uptime / 86400) . 'd ' . gmdate('H:i', $uptime) . ')';
}
}
- $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']);
- $client['gbram'] = round(round($client['mbram'] / 500) / 2, 1);
+ $client['gbram'] = round(ceil($client['mbram'] / 512) / 2, 1);
$client['gbtmp'] = round($client['id44mb'] / 1024);
+ foreach (['tmp', 'swap', 'mem'] as $item) {
+ if ($client['live_' . $item . 'size'] == 0)
+ continue;
+ $client['live_' . $item . 'percent'] = round(($client['live_' . $item . 'free'] / $client['live_' . $item . 'size']) * 100, 2);
+ $client['live_' . $item . 'free_s'] = Util::readableFileSize($client['live_' . $item . 'free'], -1, 2);
+ }
$client['ramclass'] = $this->ramColorClass($client['mbram']);
$client['kvmclass'] = $this->kvmColorClass($client['kvmstate']);
$client['hddclass'] = $this->hddColorClass($client['gbtmp']);
@@ -856,7 +881,7 @@ class Page_Statistics extends Page
Parser::parsePci($client['lspci1'], $client['lspci2'], $section[2]);
}
if (isset($hdds['hdds']) && $section[1] === 'smartctl') {
- // This currently required that the partition table section comes first...
+ // This currently requires that the partition table section comes first...
Parser::parseSmartctl($hdds['hdds'], $section[2]);
}
}
@@ -891,6 +916,7 @@ class Page_Statistics extends Page
$client['screens'][] = $row;
}
array_multisort($ports, SORT_ASC, $client['screens']);
+ Permission::addGlobalTags($client['perms'], null, ['hardware.projectors.edit', 'hardware.projectors.view']);
// Throw output at user
Render::addTemplate('machine-main', $client);
// Sessions
@@ -899,16 +925,18 @@ class Page_Statistics extends Page
//if ($cutoff < $client['firstseen']) $cutoff = $client['firstseen'];
$scale = 100 / ($NOW - $cutoff);
$res = Database::simpleQuery('SELECT dateline, typeid, data FROM statistic'
- . " WHERE dateline > :cutoff AND typeid IN ('~session-length', '~offline-length') AND machineuuid = :uuid ORDER BY dateline ASC", array(
+ . " WHERE dateline > :cutoff AND typeid IN (:sessionLength, :offlineLength) AND machineuuid = :uuid ORDER BY dateline ASC", array(
'cutoff' => $cutoff - 86400 * 14,
'uuid' => $uuid,
+ 'sessionLength' => Statistics::SESSION_LENGTH,
+ 'offlineLength' => Statistics::OFFLINE_LENGTH,
));
$spans['rows'] = array();
$spans['graph'] = '';
$last = false;
$first = true;
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if (!$client['isclient'] && $row['typeid'] === '~session-length')
+ if (!$client['isclient'] && $row['typeid'] === Statistics::SESSION_LENGTH)
continue; // Don't differentiate between session and idle for non-clients
if ($first && $row['dateline'] > $cutoff && $client['lastboot'] > $cutoff) {
// Special case: offline before
@@ -934,9 +962,12 @@ class Page_Statistics extends Page
}
$row['from'] = Util::prettyTime($row['dateline']);
$row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']);
- if ($row['typeid'] === '~offline-length') {
+ if ($row['typeid'] === Statistics::OFFLINE_LENGTH) {
$row['glyph'] = 'off';
$color = '#444';
+ } elseif ($row['typeid'] === Statistics::SUSPEND_LENGTH) {
+ $row['glyph'] = 'pause';
+ $color = '#686';
} else {
$row['glyph'] = 'user';
$color = '#e77';
@@ -956,8 +987,26 @@ class Page_Statistics extends Page
}
if ($client['state'] === 'OCCUPIED') {
$spans['graph'] .= '<div style="background:#e99;left:' . round(($client['logintime'] - $cutoff) * $scale, 2) . '%;width:' . round(($NOW - $client['logintime'] + 900) * $scale, 2) . '%">&nbsp;</div>';
+ $spans['rows'][] = [
+ 'from' => Util::prettyTime($client['logintime']),
+ 'duration' => '-',
+ 'glyph' => 'user',
+ ];
+ $row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']);
} elseif ($client['state'] === 'OFFLINE') {
$spans['graph'] .= '<div style="background:#444;left:' . round(($client['lastseen'] - $cutoff) * $scale, 2) . '%;width:' . round(($NOW - $client['lastseen'] + 900) * $scale, 2) . '%">&nbsp;</div>';
+ $spans['rows'][] = [
+ 'from' => Util::prettyTime($client['lastseen']),
+ 'duration' => '-',
+ 'glyph' => 'off',
+ ];
+ } elseif ($client['state'] === 'STANDBY') {
+ $spans['graph'] .= '<div style="background:#686;left:' . round(($client['lastseen'] - $cutoff) * $scale, 2) . '%;width:' . round(($NOW - $client['lastseen'] + 900) * $scale, 2) . '%">&nbsp;</div>';
+ $spans['rows'][] = [
+ 'from' => Util::prettyTime($client['lastseen']),
+ 'duration' => '-',
+ 'glyph' => 'pause',
+ ];
}
$t = explode('-', date('Y-n-j-G', $cutoff));
if ($t[3] >= 8 && $t[3] <= 22) {
@@ -1002,8 +1051,10 @@ class Page_Statistics extends Page
));
}
// Notes
- $client["notesAllowed"] = User::hasPermission("note", $client["locationid"]);
- Render::addTemplate('machine-notes', $client);
+ if (User::hasPermission('machine.note.*', (int)$client['locationid'])) {
+ Permission::addGlobalTags($client['perms'], (int)$client['locationid'], ['machine.note.edit']);
+ Render::addTemplate('machine-notes', $client);
+ }
}
private function eventToIconName($event)
@@ -1026,6 +1077,8 @@ class Page_Statistics extends Page
protected function doAjax()
{
+ if (!User::load())
+ return;
$param = Request::any('lookup', false, 'string');
if ($param === false) {
die('No lookup given');
@@ -1089,3 +1142,5 @@ class Page_Statistics extends Page
), true);
}
}
+
+Page_Statistics::initConstants();
diff --git a/modules-available/statistics/pages/projectors.inc.php b/modules-available/statistics/pages/projectors.inc.php
index cde542c6..cc808cf0 100644
--- a/modules-available/statistics/pages/projectors.inc.php
+++ b/modules-available/statistics/pages/projectors.inc.php
@@ -13,12 +13,13 @@ class SubPage
private static function handleProjector($action)
{
+ User::assertPermission('hardware.projectors.edit');
$hwid = Request::post('hwid', false, 'int');
if ($hwid === false) {
Util::traceError('Param hwid missing');
}
if ($action === 'addprojector') {
- Database::exec('INSERT INTO statistic_hw_prop (hwid, prop, value)'
+ Database::exec('INSERT IGNORE INTO statistic_hw_prop (hwid, prop, value)'
. ' VALUES (:hwid, :prop, :value)', array(
'hwid' => $hwid,
'prop' => 'projector',
@@ -43,6 +44,7 @@ class SubPage
private static function showProjectors()
{
+ User::assertPermission('hardware.projectors.*');
$res = Database::simpleQuery('SELECT h.hwname, h.hwid FROM statistic_hw h'
. " INNER JOIN statistic_hw_prop p ON (h.hwid = p.hwid AND p.prop = :projector)"
. " WHERE h.hwtype = :screen ORDER BY h.hwname ASC", array(
diff --git a/modules-available/statistics/permissions/permissions.json b/modules-available/statistics/permissions/permissions.json
index 97a49036..663a8dc4 100644
--- a/modules-available/statistics/permissions/permissions.json
+++ b/modules-available/statistics/permissions/permissions.json
@@ -1,5 +1,26 @@
-[
- "view",
- "note",
- "delete"
-] \ No newline at end of file
+{
+ "machine.delete": {
+ "location-aware": true
+ },
+ "machine.note.view": {
+ "location-aware": true
+ },
+ "machine.note.edit": {
+ "location-aware": true
+ },
+ "hardware.projectors.view": {
+ "location-aware": false
+ },
+ "hardware.projectors.edit": {
+ "location-aware": false
+ },
+ "machine.view-details": {
+ "location-aware": true
+ },
+ "view.summary": {
+ "location-aware": true
+ },
+ "view.list": {
+ "location-aware": true
+ }
+} \ No newline at end of file
diff --git a/modules-available/statistics/style.css b/modules-available/statistics/style.css
index 1496ac87..c48275ba 100644
--- a/modules-available/statistics/style.css
+++ b/modules-available/statistics/style.css
@@ -8,4 +8,36 @@
border-radius: 25px;
font-size: 20px;
line-height: 40px;
+}
+
+.meter {
+ position: relative;
+ border-radius: 5px;
+ border: 1px solid #999;
+ background: linear-gradient(to right, #9e6 0%, #fb8 66%, #f32 100%);
+ height: 1.25em;
+ padding: 0;
+ width: 100%;
+ overflow: hidden;
+}
+
+.meter .bar {
+ position: absolute;
+ top: 0;
+ height: 100%;
+ right: 0;
+ background: #efe;
+ display: inline-block;
+ padding: 0;
+ margin: 0 0 0 auto;
+}
+
+.meter .text {
+ position: absolute;
+ right: 5px;
+ overflow: visible;
+ font-size: 8pt;
+ white-space: nowrap;
+ z-index: 1000;
+ text-shadow: #fff 1px 1px;
} \ No newline at end of file
diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html
index d06eb4f7..18a5d10a 100644
--- a/modules-available/statistics/templates/clientlist.html
+++ b/modules-available/statistics/templates/clientlist.html
@@ -34,6 +34,11 @@
<span class="glyphicon glyphicon-filter"></span>
</button>
</td>
+ <td>
+ <button type="button" class="btn btn-default btn-xs" onclick="popupFilter('location')">
+ <span class="glyphicon glyphicon-filter"></span>
+ </button>
+ </td>
</tr>
<tr>
<th data-sort="string">{{lang_machine}}</th>
@@ -43,18 +48,17 @@
<th data-sort="int" class="text-right">{{lang_gbRam}}</th>
<th data-sort="int" class="text-right">{{lang_tmpGb}}</th>
<th data-sort="int">{{lang_cpuModel}}</th>
+ <th data-sort="string">{{lang_location}}</th>
</tr>
</thead>
<tbody>
{{#rows}}
<tr>
<td data-sort-value="{{hostname}}" class="text-nowrap">
- {{#deleteAllowed}}
- <div class="checkbox checkbox-inline">
- <input type="checkbox" name="uuid[]" value="{{machineuuid}}" class="deleteCheckboxes">
- <label></label>
- </div>
- {{/deleteAllowed}}
+ <div class="checkbox checkbox-inline">
+ <input type="checkbox" name="uuid[]" value="{{machineuuid}}" class="deleteCheckboxes" {{delete_disabled}}>
+ <label></label>
+ </div>
{{#hasnotes}}
<span class="glyphicon glyphicon-exclamation-sign pull-right"></span>
{{/hasnotes}}
@@ -70,7 +74,13 @@
{{#state_STANDBY}}
<span class="glyphicon glyphicon-off green" title="{{lang_machineStandby}}"></span>
{{/state_STANDBY}}
- <a href="?do=Statistics&amp;uuid={{machineuuid}}"><b>{{hostname}}</b></a>
+ {{#link_details}}
+ <a href="?do=Statistics&amp;uuid={{machineuuid}}">
+ {{/link_details}}
+ <b>{{hostname}}</b>
+ {{#link_details}}
+ </a>
+ {{/link_details}}
<div class="small">{{machineuuid}}</div>
{{#rmmodule}}
<div class="small">{{lang_runMode}}:
@@ -93,6 +103,7 @@
</div>{{/nohdd}}
</td>
<td data-sort-value="{{realcores}}">{{lang_realCores}}: {{realcores}}<div class="small">{{cpumodel}}</div></td>
+ <td data-sort-value="{{locationname}}">{{locationname}}</td>
</tr>
{{/rows}}
</tbody>
diff --git a/modules-available/statistics/templates/cpumodels.html b/modules-available/statistics/templates/cpumodels.html
index d684c914..d89a5b2f 100644
--- a/modules-available/statistics/templates/cpumodels.html
+++ b/modules-available/statistics/templates/cpumodels.html
@@ -19,11 +19,11 @@
<tr id="{{id}}" class="{{collapse}}">
<td data-sort-value="{{systemmodel}}" class="text-left text-nowrap filter-col" data-filter-col="systemmodel">
<table style="width:100%; table-layout: fixed;"><tr><td style="overflow:hidden;text-overflow: ellipsis;">
- <a class="filter-val" data-filter-val="{{systemmodel}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~systemmodel={{urlsystemmodel}}">{{systemmodel}}</a>
+ <a class="filter-val" data-filter-val="{{systemmodel}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~systemmodel={{urlsystemmodel}}">{{systemmodel}}</a>
</td></tr></table>
</td>
<td data-sort-value="{{cores}}" class="text-right filter-col" data-filter-col="realcores">
- <a class="filter-val" data-filter-val="{{cores}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~realcores={{cores}}">{{cores}}</a>
+ <a class="filter-val" data-filter-val="{{cores}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~realcores={{cores}}">{{cores}}</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html
index 58b66a75..07aa7320 100644
--- a/modules-available/statistics/templates/filterbox.html
+++ b/modules-available/statistics/templates/filterbox.html
@@ -13,7 +13,7 @@
<select id="operatorSelect" name="operator" class="form-control col-4-xs"> </select>
</div>
<div class="form-group">
- <input name="argument" id="argumentInput" class="form-control col-4-xs"> </input>
+ <input name="argument" id="argumentInput" class="form-control col-4-xs">
<select name="argument" id="argumentSelect" class="form-control col-4-xs"> </select>
</div>
@@ -41,11 +41,11 @@
<div class="btn-group pull-right">
- <button class="btn btn-default {{statButtonClass}}" type="submit" name="show" value="stat">
+ <button class="btn btn-default {{statButtonClass}}" type="submit" name="show" value="summary" {{perms.view.summary.disabled}}>
<span class="glyphicon glyphicon-stats"></span>
{{lang_showVisualization}}
</button>
- <button class="btn btn-default {{listButtonClass}}" type="submit" name="show" value="list">
+ <button class="btn btn-default {{listButtonClass}}" type="submit" name="show" value="list" {{perms.view.list.disabled}}>
<span class="glyphicon glyphicon-list"></span>
{{lang_showList}}
</button>
@@ -101,7 +101,10 @@ var slxFilterNames = {
currentuser: '{{lang_currentUser}}',
subnet: '{{lang_subnet}}',
runtime: '{{lang_runtimeHours}}',
- hostname: '{{lang_hostname}}'
+ hostname: '{{lang_hostname}}',
+ live_swapfree: '{{lang_swapFree}}',
+ live_memfree: '{{lang_memFree}}',
+ live_tmpfree: '{{lang_tmpFree}}'
};
slxLocations = {{{locations}}};
@@ -169,16 +172,16 @@ document.addEventListener("DOMContentLoaded", function () {
}));
});
/* also set the type of the input */
- if (columns[col]['type'] == 'date') {
+ if (columns[col]['type'] === 'date') {
$('#argumentInput').datepicker({format : 'yyyy-mm-dd'});
$('#argumentSelect').hide();
- } else if(columns[col]['type'] == 'enum') {
+ } else if(columns[col]['type'] === 'enum') {
$('#argumentSelect').empty();
$('#argumentInput').hide();
$('#argumentSelect').show();
columns[col]['values'].forEach(function (v) {
var t = v;
- var disabled = true;
+ var disabled = (col === 'location');
if (col === 'location' && slxLocations['L' + v]) {
t = slxLocations['L' + v].pad + ' ' + slxLocations['L' + v].name;
disabled = slxLocations['L' + v].disabled;
diff --git a/modules-available/statistics/templates/id44.html b/modules-available/statistics/templates/id44.html
index d3b1ab1c..de1c71ad 100644
--- a/modules-available/statistics/templates/id44.html
+++ b/modules-available/statistics/templates/id44.html
@@ -17,7 +17,7 @@
{{#rows}}
<tr id="tmpid{{gb}}" class="{{class}} {{collapse}}">
<td data-sort-value="{{gb}}" class="text-left text-nowrap">
- <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~hddgb={{gb}}">{{gb}}&thinsp;GiB</a>
+ <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~hddgb={{gb}}">{{gb}}&thinsp;GiB</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/kvmstate.html b/modules-available/statistics/templates/kvmstate.html
index 3704eda0..efa3bad3 100644
--- a/modules-available/statistics/templates/kvmstate.html
+++ b/modules-available/statistics/templates/kvmstate.html
@@ -17,7 +17,7 @@
{{#rows}}
<tr id="kvm{{kvmstate}}">
<td data-sort-value="{{kvmstate}}" class="text-left text-nowrap">
- <a class="filter-val" data-filter-val="{{kvmstate}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~kvmstate={{kvmstate}}">{{kvmstate}}</a>
+ <a class="filter-val" data-filter-val="{{kvmstate}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~kvmstate={{kvmstate}}">{{kvmstate}}</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/machine-hdds.html b/modules-available/statistics/templates/machine-hdds.html
index fd6cf1be..b839dfca 100644
--- a/modules-available/statistics/templates/machine-hdds.html
+++ b/modules-available/statistics/templates/machine-hdds.html
@@ -20,7 +20,7 @@
<div>{{lang_powerOnTime}}: {{s_PowerOnHours}}&thinsp;{{lang_hours}} ({{PowerOnTime}})</div>
{{/s_PowerOnHours}}
<div class="row">
- <div class="col-sm-6">
+ <div class="col-sm-7">
<table class="table table-condensed table-striped table-responsive">
<tr>
<th>{{lang_partName}}</th>
@@ -30,14 +30,14 @@
{{#partitions}}
<tr id="{{id}}">
<td>{{name}}</td>
- <td class="text-right">{{size}}&thinsp;GiB</td>
+ <td class="text-right text-nowrap">{{size}}&thinsp;GiB</td>
<td>{{type}}</td>
</tr>
{{/partitions}}
</table>
<div class="slx-bold">{{lang_total}}: {{size}}&thinsp;GiB</div>
</div>
- <div class="col-sm-6">
+ <div class="col-sm-5">
<canvas id="{{devid}}-chart" style="width:100%;height:250px"></canvas>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
diff --git a/modules-available/statistics/templates/machine-main.html b/modules-available/statistics/templates/machine-main.html
index d8f2c521..44f03a99 100644
--- a/modules-available/statistics/templates/machine-main.html
+++ b/modules-available/statistics/templates/machine-main.html
@@ -117,9 +117,23 @@
<tr class="{{ramclass}}">
<td class="text-nowrap">{{lang_ram}}</td>
<td>
- {{gbram}}&thinsp;GiB
- {{#maxram}}({{lang_maximumAbbrev}} {{maxram}}){{/maxram}}
- {{ramtype}}
+ <div>
+ {{gbram}}&thinsp;GiB
+ {{#maxram}}({{lang_maximumAbbrev}} {{maxram}}){{/maxram}}
+ {{ramtype}}
+ </div>
+ {{#live_memsize}}
+ <div class="meter">
+ <div class="text">{{live_memfree_s}} {{lang_free}}</div>
+ <div class="bar" style="width:{{live_mempercent}}%"></div>
+ </div>
+ {{/live_memsize}}
+ {{#live_swapsize}}
+ <div class="meter">
+ <div class="text">{{live_swapfree_s}} {{lang_free}}</div>
+ <div class="bar" style="width:{{live_swappercent}}%"></div>
+ </div>
+ {{/live_swapsize}}
</td>
</tr>
{{#extram}}
@@ -135,7 +149,17 @@
{{/extram}}
<tr class="{{hddclass}}">
<td class="text-nowrap">{{lang_tempPart}}</td>
- <td>{{gbtmp}}&thinsp;GiB</td>
+ <td>
+ <div>
+ {{gbtmp}}&thinsp;GiB
+ </div>
+ {{#live_tmpsize}}
+ <div class="meter">
+ <div class="text">{{live_tmpfree_s}} {{lang_free}}</div>
+ <div class="bar" style="width:{{live_tmppercent}}%"></div>
+ </div>
+ {{/live_tmpsize}}
+ </td>
</tr>
<tr class="{{kvmclass}}">
<td class="text-nowrap">{{lang_64bitSupport}}</td>
@@ -157,13 +181,19 @@
{{#hwname}}
<div class="pull-right btn-group btn-group-xs">
{{#projector}}
- <a href="?do=statistics&amp;show=projectors" class="btn btn-default">{{lang_projector}}</a>
+ <a href="?do=statistics&amp;show=projectors" class="btn btn-default {{perms.hardware.projectors.view.disabled}}">
+ {{lang_projector}}
+ </a>
<button form="delprojector" type="submit" name="hwid" value="{{hwid}}"
- class="btn btn-danger"><span class="glyphicon glyphicon-remove"></span></button>
+ class="btn btn-danger" {{perms.hardware.projectors.edit.disabled}}>
+ <span class="glyphicon glyphicon-remove"></span>
+ </button>
{{/projector}}
{{^projector}}
<button form="addprojector" type="submit" name="hwid" value="{{hwid}}"
- class="btn btn-success"><span class="glyphicon glyphicon-plus"></span> {{lang_projector}}</button>
+ class="btn btn-success" {{perms.hardware.projectors.edit.disabled}}>
+ <span class="glyphicon glyphicon-plus"></span> {{lang_projector}}
+ </button>
{{/projector}}
</div>
{{/hwname}}
diff --git a/modules-available/statistics/templates/machine-notes.html b/modules-available/statistics/templates/machine-notes.html
index 66e44da4..c352580f 100644
--- a/modules-available/statistics/templates/machine-notes.html
+++ b/modules-available/statistics/templates/machine-notes.html
@@ -8,9 +8,12 @@
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="setnotes">
<input type="hidden" name="uuid" value="{{machineuuid}}">
- <textarea name="content" class="form-control" cols="101" rows="10" {{^notesAllowed}}disabled{{/notesAllowed}}>{{notes}}</textarea>
+ <textarea name="content" class="form-control" cols="101" rows="10" {{perms.machine.note.edit.disabled}}>{{notes}}</textarea>
<br/>
- <button type="submit" class="btn btn-primary pull-right" {{^notesAllowed}}disabled{{/notesAllowed}}><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button type="submit" class="btn btn-primary pull-right" {{perms.machine.note.edit.disabled}}>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
</form>
</div>
</div>
diff --git a/modules-available/statistics/templates/memory.html b/modules-available/statistics/templates/memory.html
index 6bc13980..cfb86062 100644
--- a/modules-available/statistics/templates/memory.html
+++ b/modules-available/statistics/templates/memory.html
@@ -17,7 +17,7 @@
{{#rows}}
<tr id="ramid{{gb}}" class="{{class}} {{collapse}}">
<td class="text-left text-nowrap" data-sort-value="{{gb}}">
- <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~gbram={{gb}}">{{gb}}&thinsp;GiB</a>
+ <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~gbram={{gb}}">{{gb}}&thinsp;GiB</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/summary.html b/modules-available/statistics/templates/summary.html
index fe9559ed..3ede7bc5 100644
--- a/modules-available/statistics/templates/summary.html
+++ b/modules-available/statistics/templates/summary.html
@@ -8,8 +8,8 @@
{{/runmode}}
<div>
{{lang_knownMachines}}: <b>{{known}}</b>&emsp;
- <a href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~state=on">{{lang_onlineMachines}}</a>: <b>{{online}}</b>&emsp;
- <a href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~state=occupied">{{lang_inUseMachines}}</a>: <b>{{used}}</b> (<b>{{usedpercent}}%</b>)
+ <a href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~state=on">{{lang_onlineMachines}}</a>: <b>{{online}}</b>&emsp;
+ <a href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~state=occupied">{{lang_inUseMachines}}</a>: <b>{{used}}</b> (<b>{{usedpercent}}%</b>)
</div>
{{#badhdd}}
<div>
diff --git a/modules-available/statistics_reporting/config.json b/modules-available/statistics_reporting/config.json
index 78ca35ba..c439efa8 100644
--- a/modules-available/statistics_reporting/config.json
+++ b/modules-available/statistics_reporting/config.json
@@ -1,4 +1,9 @@
{
"category": "main.status",
- "dependencies": [ "statistics", "locations", "js_stupidtable", "js_jqueryui" ]
-}
+ "dependencies": [
+ "statistics",
+ "locations",
+ "js_stupidtable",
+ "js_jqueryui"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/statistics_reporting/inc/queries.inc.php b/modules-available/statistics_reporting/inc/queries.inc.php
index 395bb548..58e9e63b 100644
--- a/modules-available/statistics_reporting/inc/queries.inc.php
+++ b/modules-available/statistics_reporting/inc/queries.inc.php
@@ -326,9 +326,9 @@ class Queries
public static function getUserStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) {
$res = Database::simpleQuery("SELECT username AS name, COUNT(*) AS 'count'
FROM statistic
- WHERE typeid='.vmchooser-session-name' AND dateline >= :from and dateline <= :to
- AND FROM_UNIXTIME(dateline, '%H') >= :lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < :upperTimeBound
- GROUP BY username", compact('from', 'to', 'lowerTimeBound', 'upperTimeBound'));
+ WHERE typeid='.vmchooser-session-name' AND dateline >= $from and dateline <= $to
+ AND FROM_UNIXTIME(dateline, '%H') >= $lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < $upperTimeBound
+ GROUP BY username");
return $res;
}
@@ -336,9 +336,9 @@ class Queries
public static function getVMStatistics($from, $to, $lowerTimeBound = 0, $upperTimeBound = 24) {
$res = Database::simpleQuery("SELECT data AS name, COUNT(*) AS 'count'
FROM statistic
- WHERE typeid='.vmchooser-session-name' AND dateline >= :from and dateline <= :to
- AND FROM_UNIXTIME(dateline, '%H') >= :lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < :upperTimeBound
- GROUP BY data", compact('from', 'to', 'lowerTimeBound', 'upperTimeBound'));
+ WHERE typeid='.vmchooser-session-name' AND dateline >= $from and dateline <= $to
+ AND FROM_UNIXTIME(dateline, '%H') >= $lowerTimeBound AND FROM_UNIXTIME(dateline, '%H') < $upperTimeBound
+ GROUP BY data");
return $res;
}
diff --git a/modules-available/statistics_reporting/lang/de/template-tags.json b/modules-available/statistics_reporting/lang/de/template-tags.json
index 397d93de..34c4b80b 100644
--- a/modules-available/statistics_reporting/lang/de/template-tags.json
+++ b/modules-available/statistics_reporting/lang/de/template-tags.json
@@ -14,6 +14,7 @@
"lang_reportingDescription": "Helfen Sie uns bwLehrpool durch das w\u00f6chentliche Verschicken eines anonymisierten Statistikberichts zu verbessern. Wenn Sie den Inhalt eines solchen Reports genauer inspizieren wollen, k\u00f6nnen Sie \u00fcber den untenstehenden Button einen aktuellen Report Ihres Servers herunterladen.",
"lang_reportingLabel": "Anonymisierte Nutzungsstatistiken \u00fcbermitteln",
"lang_sessions": "Sitzungen",
+ "lang_settings": "Einstellungen",
"lang_shortSessions": "Sitzungen < 60s",
"lang_show": "Anzeigen",
"lang_total": "Gesamt",
@@ -22,6 +23,5 @@
"lang_totalSessionTime": "Belegt",
"lang_totalStandbyTime": "Standby",
"lang_totalTime": "Gesamtzeit",
- "lang_user": "Nutzer",
"lang_vm": "Veranstaltung"
} \ No newline at end of file
diff --git a/modules-available/statistics_reporting/lang/en/template-tags.json b/modules-available/statistics_reporting/lang/en/template-tags.json
index a4d19222..7ddc3973 100644
--- a/modules-available/statistics_reporting/lang/en/template-tags.json
+++ b/modules-available/statistics_reporting/lang/en/template-tags.json
@@ -14,6 +14,7 @@
"lang_reportingDescription": "Help us improve bwLehrpool by automatically sending an anonymized statistics report once a week. If you want to check what data the report contains, you can download such a report for reference below.",
"lang_reportingLabel": "Send anonymized usage statistics",
"lang_sessions": "Sessions",
+ "lang_settings": "Settings",
"lang_shortSessions": "Sessions < 60s",
"lang_show": "Show",
"lang_total": "Total",
@@ -22,6 +23,5 @@
"lang_totalSessionTime": "Occupied",
"lang_totalStandbyTime": "Standby",
"lang_totalTime": "Total Time",
- "lang_user": "User",
"lang_vm": "Lecture"
} \ No newline at end of file
diff --git a/modules-available/statistics_reporting/lang/pt/template-tags.json b/modules-available/statistics_reporting/lang/pt/template-tags.json
deleted file mode 100644
index e7981844..00000000
--- a/modules-available/statistics_reporting/lang/pt/template-tags.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "lang_hello": "Olá"
-} \ No newline at end of file
diff --git a/modules-available/statistics_reporting/page.inc.php b/modules-available/statistics_reporting/page.inc.php
index b30b5cab..cc03e4d8 100644
--- a/modules-available/statistics_reporting/page.inc.php
+++ b/modules-available/statistics_reporting/page.inc.php
@@ -84,6 +84,7 @@ class Page_Statistics_Reporting extends Page
die(json_encode($report));
}
}
+ User::assertPermission('*');
}
/**
@@ -283,6 +284,7 @@ class Page_Statistics_Reporting extends Page
private function fetchData($flags)
{
+ // TODO: Make all modes location-aware, filter while querying, not after
switch ($this->type) {
case 'total':
return GetData::total($flags);
@@ -309,7 +311,7 @@ class Page_Statistics_Reporting extends Page
case 'client':
$data = GetData::perClient($flags, Request::any('new', false, 'string'));
// only show clients from locations which you have permission for
- $filterLocs = User::getAllowedLocations("table.view.location");
+ $filterLocs = User::getAllowedLocations("table.view.client");
foreach ($data as $key => $row) {
if (!in_array($row['locationid'], $filterLocs)) {
unset($data[$key]);
diff --git a/modules-available/statistics_reporting/permissions/permissions.json b/modules-available/statistics_reporting/permissions/permissions.json
index d967b75d..1244027e 100644
--- a/modules-available/statistics_reporting/permissions/permissions.json
+++ b/modules-available/statistics_reporting/permissions/permissions.json
@@ -1,10 +1,26 @@
-[
- "table.view.total",
- "table.view.location",
- "table.view.client",
- "table.view.user",
- "table.view.vm",
- "table.export",
- "reporting.download",
- "reporting.change"
-] \ No newline at end of file
+{
+ "reporting.change": {
+ "location-aware": false
+ },
+ "reporting.download": {
+ "location-aware": false
+ },
+ "table.export": {
+ "location-aware": false
+ },
+ "table.view.client": {
+ "location-aware": true
+ },
+ "table.view.location": {
+ "location-aware": true
+ },
+ "table.view.total": {
+ "location-aware": false
+ },
+ "table.view.user": {
+ "location-aware": false
+ },
+ "table.view.vm": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/summernote/config.json b/modules-available/summernote/config.json
index 5a0c7960..69bb0aa9 100644
--- a/modules-available/summernote/config.json
+++ b/modules-available/summernote/config.json
@@ -1,9 +1,10 @@
{
- "dependencies" : [],
- "css": {
- "style.css": true
- },
- "scripts": {
- "clientscript.js": true
- }
-}
+ "dependencies": [],
+ "css": [
+ "style.css"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ],
+ "client-plugin": true
+} \ No newline at end of file
diff --git a/modules-available/support/config.json b/modules-available/support/config.json
index 706412d0..110f8b67 100644
--- a/modules-available/support/config.json
+++ b/modules-available/support/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.content"
-}
+ "category": "main.content"
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/addmodule_adauth.inc.php b/modules-available/sysconfig/addmodule_adauth.inc.php
index df7f385d..fa2f5258 100644
--- a/modules-available/sysconfig/addmodule_adauth.inc.php
+++ b/modules-available/sysconfig/addmodule_adauth.inc.php
@@ -13,7 +13,7 @@ class AdAuth_Start extends AddModule_Base
protected function renderInternal()
{
- $ADAUTH_COMMON_FIELDS = array('title', 'server', 'searchbase', 'binddn', 'bindpw', 'home', 'homeattr', 'ssl', 'fixnumeric', 'certificate', 'mapping');
+ $ADAUTH_COMMON_FIELDS = array('title', 'server', 'searchbase', 'binddn', 'bindpw', 'home', 'homeattr', 'ssl', 'fixnumeric', 'genuid', 'certificate', 'mapping');
$data = array();
if ($this->edit !== false) {
moduleToArray($this->edit, $data, $ADAUTH_COMMON_FIELDS);
@@ -107,6 +107,7 @@ class AdAuth_CheckConnection extends AddModule_Base
'home' => Request::post('home'),
'ssl' => Request::post('ssl'),
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'certificate' => Request::post('certificate', ''),
'taskid' => $this->scanTask['id'],
'mapping' => ConfigModuleBaseLdap::getMapping($mapping),
@@ -208,6 +209,7 @@ class AdAuth_SelfSearch extends AddModule_Base
'home' => Request::post('home'),
'ssl' => Request::post('ssl') === 'on',
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'fingerprint' => Request::post('fingerprint'),
'certificate' => Request::post('certificate', ''),
'originalbinddn' => $this->originalBindDn,
@@ -285,6 +287,7 @@ class AdAuth_HomeAttrCheck extends AddModule_Base
'home' => Request::post('home'),
'ssl' => Request::post('ssl') === 'on',
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'fingerprint' => Request::post('fingerprint'),
'certificate' => Request::post('certificate', ''),
'originalbinddn' => Request::post('originalbinddn'),
@@ -357,6 +360,7 @@ class AdAuth_CheckCredentials extends AddModule_Base
'homeattr' => Request::post('homeattr'),
'ssl' => Request::post('ssl') === 'on',
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'fingerprint' => Request::post('fingerprint'),
'certificate' => Request::post('certificate', ''),
'originalbinddn' => Request::post('originalbinddn'),
@@ -421,6 +425,7 @@ class AdAuth_HomeDir extends AddModule_Base
'homeattr' => Request::post('homeattr'),
'ssl' => Request::post('ssl') === 'on',
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'fingerprint' => Request::post('fingerprint'),
'certificate' => Request::post('certificate', ''),
'originalbinddn' => Request::post('originalbinddn'),
@@ -434,9 +439,11 @@ class AdAuth_HomeDir extends AddModule_Base
$data[$key . '_c'] = 'checked="checked"';
}
}
- $data['shareRemapMode_' . $this->edit->getData('shareRemapMode')] = 'selected="selected"';
- $data['shareDomain'] = $this->edit->getData('shareDomain');
$letter = $this->edit->getData('shareHomeDrive');
+ $data['shareRemapMode_' . $this->edit->getData('shareRemapMode')] = 'selected="selected"';
+ foreach (['shareDomain', 'shareHomeMountOpts', 'ldapAttrMountOpts'] as $key) {
+ $data[$key] = $this->edit->getData($key);
+ }
} else {
$data['shareDownloads_c'] = $data['shareMedia_c'] = $data['shareDocuments_c'] = $data['shareRemapCreate_c'] = 'checked="checked"';
$data['shareRemapMode_1'] = 'selected="selected"';
@@ -475,16 +482,12 @@ class AdAuth_Finish extends AddModule_Base
else
$module = $this->edit;
$ssl = Request::post('ssl', 'off') === 'on';
- $module->setData('server', Request::post('server'));
- $module->setData('searchbase', Request::post('searchbase'));
- $module->setData('binddn', Request::post('binddn'));
- $module->setData('bindpw', Request::post('bindpw'));
- $module->setData('home', Request::post('home'));
- $module->setData('homeattr', Request::post('homeattr'));
- $module->setData('certificate', Request::post('certificate'));
+ foreach (['searchbase', 'binddn', 'server', 'bindpw', 'home', 'homeattr', 'certificate', 'fixnumeric', 'genuid',
+ 'ldapAttrMountOpts', 'shareHomeMountOpts'] as $key) {
+ $module->setData($key, Request::post($key, '', 'string'));
+ }
$module->setData('ssl', $ssl);
$module->setData('mapping', Request::post('mapping', false, 'array'));
- $module->setData('fixnumeric', Request::post('fixnumeric', '', 'string'));
foreach (AdAuth_HomeDir::getAttributes() as $key) {
$value = Request::post($key);
if (is_numeric($value)) {
diff --git a/modules-available/sysconfig/addmodule_custommodule.inc.php b/modules-available/sysconfig/addmodule_custommodule.inc.php
index 8c24a071..c234f765 100644
--- a/modules-available/sysconfig/addmodule_custommodule.inc.php
+++ b/modules-available/sysconfig/addmodule_custommodule.inc.php
@@ -62,7 +62,7 @@ class CustomModule_ProcessUpload extends AddModule_Base
unlink($tempfile);
$this->tmError();
}
- if ($status['statusCode'] != TASK_FINISHED) {
+ if ($status['statusCode'] != Taskmanager::TASK_FINISHED) {
unlink($tempfile);
$this->taskError($status);
}
@@ -128,7 +128,7 @@ class CustomModule_CompressModule extends AddModule_Base
if (!isset($status['statusCode'])) {
$this->tmError();
}
- if ($status['statusCode'] != TASK_FINISHED) {
+ if ($status['statusCode'] != Taskmanager::TASK_FINISHED) {
$this->taskError($status);
}
// Seems ok, create entry
diff --git a/modules-available/sysconfig/addmodule_ldapauth.inc.php b/modules-available/sysconfig/addmodule_ldapauth.inc.php
index 1db6cb51..126a6549 100644
--- a/modules-available/sysconfig/addmodule_ldapauth.inc.php
+++ b/modules-available/sysconfig/addmodule_ldapauth.inc.php
@@ -9,7 +9,7 @@ class LdapAuth_Start extends AddModule_Base
protected function renderInternal()
{
- $LDAPAUTH_COMMON_FIELDS = array('title', 'server', 'searchbase', 'binddn', 'bindpw', 'home', 'homeattr', 'ssl', 'fixnumeric', 'certificate', 'mapping');
+ $LDAPAUTH_COMMON_FIELDS = array('title', 'server', 'searchbase', 'binddn', 'bindpw', 'home', 'homeattr', 'ssl', 'fixnumeric', 'genuid', 'certificate', 'mapping');
$data = array();
if ($this->edit !== false) {
moduleToArray($this->edit, $data, $LDAPAUTH_COMMON_FIELDS);
@@ -81,6 +81,7 @@ class LdapAuth_CheckConnection extends AddModule_Base
'home' => Request::post('home'),
'ssl' => Request::post('ssl'),
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'certificate' => Request::post('certificate', ''),
'taskid' => $this->scanTask['id'],
'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')),
@@ -152,6 +153,7 @@ class LdapAuth_CheckCredentials extends AddModule_Base
'home' => Request::post('home'),
'ssl' => Request::post('ssl') === 'on',
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'fingerprint' => Request::post('fingerprint'),
'certificate' => Request::post('certificate', ''),
'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')),
@@ -192,6 +194,7 @@ class LdapAuth_HomeDir extends AddModule_Base
'home' => Request::post('home'),
'ssl' => Request::post('ssl') === 'on',
'fixnumeric' => Request::post('fixnumeric'),
+ 'genuid' => Request::post('genuid'),
'fingerprint' => Request::post('fingerprint'),
'certificate' => Request::post('certificate', ''),
'originalbinddn' => Request::post('originalbinddn'),
@@ -205,9 +208,11 @@ class LdapAuth_HomeDir extends AddModule_Base
$data[$key . '_c'] = 'checked="checked"';
}
}
- $data['shareRemapMode_' . $this->edit->getData('shareRemapMode')] = 'selected="selected"';
- $data['shareDomain'] = $this->edit->getData('shareDomain');
$letter = $this->edit->getData('shareHomeDrive');
+ $data['shareRemapMode_' . $this->edit->getData('shareRemapMode')] = 'selected="selected"';
+ foreach (['shareDomain', 'shareHomeMountOpts', 'ldapAttrMountOpts'] as $key) {
+ $data[$key] = $this->edit->getData($key);
+ }
} else {
$data['shareDownloads_c'] = $data['shareMedia_c'] = $data['shareDocuments_c'] = $data['shareRemapCreate_c'] = 'checked="checked"';
$data['shareRemapMode_1'] = 'selected="selected"';
@@ -238,8 +243,6 @@ class LdapAuth_Finish extends AddModule_Base
protected function preprocessInternal()
{
- $binddn = Request::post('binddn');
- $searchbase = Request::post('searchbase');
$title = Request::post('title');
if (empty($title))
$title = 'LDAP: ' . Request::post('server');
@@ -248,15 +251,12 @@ class LdapAuth_Finish extends AddModule_Base
else
$module = $this->edit;
$ssl = Request::post('ssl', 'off') === 'on';
- $module->setData('server', Request::post('server'));
- $module->setData('searchbase', $searchbase);
- $module->setData('binddn', $binddn);
- $module->setData('bindpw', Request::post('bindpw'));
- $module->setData('home', Request::post('home'));
- $module->setData('certificate', Request::post('certificate'));
+ foreach (['searchbase', 'binddn', 'server', 'bindpw', 'home', 'certificate', 'fixnumeric', 'genuid',
+ 'ldapAttrMountOpts', 'shareHomeMountOpts'] as $key) {
+ $module->setData($key, Request::post($key, '', 'string'));
+ }
$module->setData('ssl', $ssl);
$module->setData('mapping', Request::post('mapping', false, 'array'));
- $module->setData('fixnumeric', Request::post('fixnumeric', '', 'string'));
foreach (LdapAuth_HomeDir::getAttributes() as $key) {
$value = Request::post($key);
if (is_numeric($value)) {
diff --git a/modules-available/sysconfig/api.inc.php b/modules-available/sysconfig/api.inc.php
index 897b44a7..bb2d9f5e 100644
--- a/modules-available/sysconfig/api.inc.php
+++ b/modules-available/sysconfig/api.inc.php
@@ -1,5 +1,11 @@
<?php
+// Called after updates to rebuild all configs
+if (Request::any('action') === 'rebuild' && isLocalExecution()) {
+ ConfigTgz::rebuildAllConfigs();
+ die('OK');
+}
+
$ip = $_SERVER['REMOTE_ADDR'];
if (substr($ip, 0, 7) === '::ffff:') {
$ip = substr($ip, 7);
@@ -26,7 +32,7 @@ if (Module::isAvailable('runmode')) {
}
}
if ($runmode !== false && $runmode->noSysconfig && file_exists(SysConfig::GLOBAL_MINIMAL_CONFIG)) {
- $row = array('filepath' => SysConfig::GLOBAL_MINIMAL_CONFIG);
+ $row = array('filepath' => SysConfig::GLOBAL_MINIMAL_CONFIG, 'title' => 'config');
} else {
$locationId = false;
if (Module::isAvailable('locations')) {
diff --git a/modules-available/sysconfig/config.json b/modules-available/sysconfig/config.json
index 28d71577..6c7b7146 100644
--- a/modules-available/sysconfig/config.json
+++ b/modules-available/sysconfig/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.settings-client"
-}
+ "category": "main.settings-client"
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/inc/configmodule.inc.php b/modules-available/sysconfig/inc/configmodule.inc.php
index 2cee37a9..b6db9c4f 100644
--- a/modules-available/sysconfig/inc/configmodule.inc.php
+++ b/modules-available/sysconfig/inc/configmodule.inc.php
@@ -354,7 +354,7 @@ abstract class ConfigModule
// Wait for generation if requested
if ($timeoutMs > 0 && isset($ret['id']) && !Taskmanager::isFinished($ret))
$ret = Taskmanager::waitComplete($ret, $timeoutMs);
- if ($ret === true || (isset($ret['statusCode']) && $ret['statusCode'] === TASK_FINISHED)) {
+ if ($ret === true || (isset($ret['statusCode']) && $ret['statusCode'] === Taskmanager::TASK_FINISHED)) {
// Already Finished
if (file_exists($this->moduleArchive) && !file_exists($tmpTgz))
$tmpTgz = false; // If generateInternal succeeded and there's no tmpTgz, it means the file didn't have to be updated
diff --git a/modules-available/sysconfig/inc/configmodule/adauth.inc.php b/modules-available/sysconfig/inc/configmodule/adauth.inc.php
index db06a4a4..ed7b318d 100644
--- a/modules-available/sysconfig/inc/configmodule/adauth.inc.php
+++ b/modules-available/sysconfig/inc/configmodule/adauth.inc.php
@@ -12,5 +12,5 @@ ConfigModule::registerModule(
Dictionary::translateFileModule('sysconfig', 'config-module', 'adAuth_title'), // Title
Dictionary::translateFileModule('sysconfig', 'config-module', 'adAuth_description'), // Description
Dictionary::translateFileModule('sysconfig', 'config-module', 'group_authentication'), // Group
- true // Only one per config?
+ false // Only one per config?
);
diff --git a/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php b/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php
index 1a706234..e8df2877 100644
--- a/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php
+++ b/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php
@@ -19,5 +19,5 @@ ConfigModule::registerModule(
Dictionary::translateFileModule('sysconfig', 'config-module', 'ldapAuth_title'), // Title
Dictionary::translateFileModule('sysconfig', 'config-module', 'ldapAuth_description'), // Description
Dictionary::translateFileModule('sysconfig', 'config-module', 'group_authentication'), // Group
- true // Only one per config?
+ false // Only one per config?
);
diff --git a/modules-available/sysconfig/inc/configmodulebaseldap.inc.php b/modules-available/sysconfig/inc/configmodulebaseldap.inc.php
index d6fc3ed9..9364c2e3 100644
--- a/modules-available/sysconfig/inc/configmodulebaseldap.inc.php
+++ b/modules-available/sysconfig/inc/configmodulebaseldap.inc.php
@@ -3,12 +3,13 @@
abstract class ConfigModuleBaseLdap extends ConfigModule
{
- const VERSION = 2;
+ const VERSION = 3;
private static $REQUIRED_FIELDS = array('server', 'searchbase');
private static $OPTIONAL_FIELDS = array('binddn', 'bindpw', 'home', 'ssl', 'fixnumeric', 'fingerprint', 'certificate', 'homeattr',
'shareRemapMode', 'shareRemapCreate', 'shareDocuments', 'shareDownloads', 'shareDesktop', 'shareMedia',
- 'shareOther', 'shareHomeDrive', 'shareDomain', 'credentialPassthrough', 'mapping');
+ 'shareOther', 'shareHomeDrive', 'shareDomain', 'credentialPassthrough', 'mapping', 'genuid',
+ 'ldapAttrMountOpts', 'shareHomeMountOpts');
public static function getMapping($config = false, &$empty = true)
{
@@ -66,6 +67,7 @@ abstract class ConfigModuleBaseLdap extends ConfigModule
if (!isset($config['fixnumeric'])) {
$config['fixnumeric'] = 's';
}
+ $config['genuid'] = isset($config['genuid']) && !empty($config['genuid']);
$this->preTaskmanagerHook($config);
$task = Taskmanager::submit('CreateLdapConfig', $config);
if (is_array($task) && isset($task['id'])) {
diff --git a/modules-available/sysconfig/inc/configtgz.inc.php b/modules-available/sysconfig/inc/configtgz.inc.php
index 17c9f35d..7b042cdb 100644
--- a/modules-available/sysconfig/inc/configtgz.inc.php
+++ b/modules-available/sysconfig/inc/configtgz.inc.php
@@ -63,7 +63,7 @@ class ConfigTgz
foreach ($moduleIds as $module) {
$idstr .= ',' . (int)$module; // Casting to int should make it safe
}
- $res = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_module WHERE moduleid IN ($idstr)");
+ $res = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_module WHERE moduleid IN ($idstr)");
// Delete old connections
Database::exec("DELETE FROM configtgz_x_module WHERE configid = :configid", array('configid' => $this->configId));
// Make connection
@@ -98,8 +98,13 @@ class ConfigTgz
$files = array();
// Get all config modules for system config
foreach ($this->modules as $module) {
- if (!empty($module['filepath']) && file_exists($module['filepath']))
+ if (!empty($module['filepath']) && file_exists($module['filepath'])) {
$files[] = $module['filepath'];
+ }
+ if ($module['moduletype'] === 'SshConfig') {
+ // HACK XXX TODO Global + SSH ugly
+ self::rebuildEmptyGlobalConfig();
+ }
}
$task = self::recompress($files, $this->file);
@@ -107,7 +112,7 @@ class ConfigTgz
// Wait for completion
if ($timeoutMs > 0 && !Taskmanager::isFailed($task) && !Taskmanager::isFinished($task))
$task = Taskmanager::waitComplete($task, $timeoutMs);
- if ($task === true || (isset($task['statusCode']) && $task['statusCode'] === TASK_FINISHED)) {
+ if ($task === true || (isset($task['statusCode']) && $task['statusCode'] === Taskmanager::TASK_FINISHED)) {
// Success!
$this->markUpdated();
return true;
@@ -222,13 +227,39 @@ class ConfigTgz
));
$res = Database::simpleQuery("SELECT configid FROM configtgz");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $module = self::get($row['configid']);
- if ($module !== false) {
- $module->generate();
+ $configTgz = self::get($row['configid']);
+ if ($configTgz !== false) {
+ $configTgz->generate();
}
}
// Build the global "empty" config that just includes global hooks
- self::recompress([], SysConfig::GLOBAL_MINIMAL_CONFIG);
+ self::rebuildEmptyGlobalConfig();
+ }
+
+ /**
+ * Rebuild the general "empty" config that only contains global hook modules
+ * and forced ones.
+ */
+ private static function rebuildEmptyGlobalConfig()
+ {
+ static $onceOnly = false;
+ if ($onceOnly)
+ return;
+ $onceOnly = true;
+ // HACK TODO XXX -- just stuff (global) ssh config into this one for now, needs proper fix :-(
+ $res = Database::simpleQuery("SELECT DISTINCT cm.filepath FROM configtgz_module cm
+ INNER JOIN configtgz_x_module cxm USING (moduleid)
+ INNER JOIN configtgz_location cl USING (configid)
+ WHERE cm.moduletype = 'SshConfig' AND cm.status = 'OK'
+ ORDER BY locationid ASC");
+ $extra = [];
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (file_exists($row['filepath'])) {
+ $extra[] = $row['filepath'];
+ break;
+ }
+ }
+ self::recompress($extra, SysConfig::GLOBAL_MINIMAL_CONFIG);
}
/**
@@ -258,7 +289,7 @@ class ConfigTgz
foreach ($moduleIds as $module) {
$idstr .= ',' . (int)$module; // Casting to int should make it safe
}
- $res = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_module WHERE moduleid IN ($idstr)");
+ $res = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_module WHERE moduleid IN ($idstr)");
// Make connection
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
Database::exec("INSERT INTO configtgz_x_module (configid, moduleid) VALUES (:configid, :moduleid)", array(
@@ -281,7 +312,7 @@ class ConfigTgz
$instance->configId = $ret['configid'];
$instance->configTitle = $ret['title'];
$instance->file = $ret['filepath'];
- $ret = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_x_module "
+ $ret = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_x_module "
. " INNER JOIN configtgz_module USING (moduleid) "
. " WHERE configid = :configid", array('configid' => $instance->configId));
$instance->modules = array();
@@ -310,7 +341,7 @@ class ConfigTgz
$instance->configId = $row['configid'];
$instance->configTitle = $row['title'];
$instance->file = $row['filepath'];
- $innerRes = Database::simpleQuery("SELECT moduleid, filepath, status FROM configtgz_x_module "
+ $innerRes = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_x_module "
. " INNER JOIN configtgz_module USING (moduleid) "
. " WHERE configid = :configid", array('configid' => $instance->configId));
$instance->modules = array();
diff --git a/modules-available/sysconfig/lang/de/permissions.json b/modules-available/sysconfig/lang/de/permissions.json
new file mode 100644
index 00000000..c32c488b
--- /dev/null
+++ b/modules-available/sysconfig/lang/de/permissions.json
@@ -0,0 +1,8 @@
+{
+ "config.assign": "Systemkonfiguration zuweisen",
+ "config.edit": "Systemkonfiguration bearbeiten",
+ "config.view-list": "Systemkonfigurationen anzeigen",
+ "module.download": "Konfigurationsmodul herunterladen",
+ "module.edit": "Konfigurationsmodul bearbeiten",
+ "module.view-list": "Konfigurationsmodule anzeigen"
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/lang/de/template-tags.json b/modules-available/sysconfig/lang/de/template-tags.json
index 7f8511e6..2a7a02d6 100644
--- a/modules-available/sysconfig/lang/de/template-tags.json
+++ b/modules-available/sysconfig/lang/de/template-tags.json
@@ -47,20 +47,22 @@
"lang_fixNumeric": "Numerischen Account-Namen muss ein 's' vorangestellt werden",
"lang_fixNumericDescription": "Wenn Sie diese Option aktivieren, m\u00fcssen Benutzer, deren Account-Name nur aus Ziffern besteht, diesem ein 's' voranstellen beim Login. Diese Option ist beim alten Login-Manager (KDM) zwingend erforderlich, da sonst der Loginvorgang fehlschl\u00e4gt. Mit dem neuen lightdm-basierten Login-Screen lassen sich numerische Account-Namen jedoch direkt verwenden. Wenn Sie an Ihrer Einrichtung keine numerischen Account-Namen verwenden, hat diese Option keine Auswirkung.",
"lang_folderRedirection": "Folder Redirection",
+ "lang_genUid": "uid-Nummern generieren",
+ "lang_genUidDescription": "Wenn aktiviert, generiert der Satellitenserver nummerische IDs f\u00fcr die Benutzer, anstatt diese aus dem LDAP\/AD zu extrahieren.",
"lang_generateModule": "Modul erzeugen",
"lang_handlingNotes": "Hier k\u00f6nnen Sie festlegen, wie Netzwerk-Shares (inkl. des Home-Verzeichnisses) an Virtuelle Maschinen durchgereicht werden. In \u00e4lteren Versionen von bwLehrpool wurden die VMware Shared Folders genutzt, was mit bestimmten file servern Probleme verursachen konnte. Der neue native Modus funktioniert deutlich besser, ist aber bei Windows-G\u00e4sten darauf angewiesen, dass (1) der file server smb\/cifs spricht (z.B. Windows Server, Samba unter Linux) und (2) die openslx.exe im Autostart eingebunden ist (bei den bwLehrpool Vorlagen bereits der Fall).",
"lang_helpHomeAttrHead": "Name des Home-Verzeichnis-Attributs",
"lang_helpHomeAttrText": "Hier k\u00f6nnen Sie alternativ zum fest vorgegebenem Template des Home-Verzeichnis Servers den Attributsnamen im Active Directory angeben, der diesen Pfad bereitstellt. Normalerweise ist dies \"homeDirectory\". Wird das Feld leer gelassen, versucht der Assistent, das Attribut selbstst\u00e4ndig zu ermitteln. Falls das Einbinden der Home-Verzeichnisse anschlie\u00dfend nicht funktioniert, \u00fcberpr\u00fcfen Sie bitte den Client-Log (Status->Client Log) und den LDAP-Proxy-Log (Status->Server Status).",
"lang_helpModuleConfiguration": "Konfigurationsmodule sind die Bausteine, aus denen eine Systemkonfiguration erstellt wird. Hier lassen sich sowohl generische Module durch einen Wizard anlegen, als auch komplett eigene Module erstellen (fortgeschritten, Linuxkenntnisse erforderlich).",
"lang_helpSystemConfiguration": "\u00dcber eine Systemkonfiguration wird die grundlegende Lokalisierung des bwLehrpool-Systems durchgef\u00fchrt. Dazu geh\u00f6ren Aspekte wie das Authentifizierungsverfahren f\u00fcr Benutzer (z.B. Active Directory, LDAP), Druckerkonfiguration, Home-Verzeichnisse, etc. Eine Systemkonfiguration setzt sich aus einem oder mehreren Konfigurationsmodulen zusammen, welche im angrenzenden Panel verwaltet werden k\u00f6nnen.",
- "lang_homeAttr": "Home-Attribut",
"lang_homeAttributeExplanation": "Bitte w\u00e4hlen Sie das Attribut, welches das Home-Verzeichnis der User enth\u00e4lt.",
"lang_homeFallback": "Home-Fallback",
"lang_homedirHandling": "(Home-)Verzeichnis Einbindung",
"lang_inheritFromParentLoc": "Von \u00fcbergeordnetem Ort erben",
+ "lang_ldapAttrMountOpts": "LDAP-Attribut f\u00fcr Mount-Optionen",
"lang_ldapStarted": "Der LDAP-Proxy wurde gestartet",
"lang_ldapText1": "Mit diesem Wizard k\u00f6nnen Sie Authentifizierung gegen einen LDAP-Server einrichten.",
- "lang_ldapText2": "Zu diesem Zweck wird ein LDAP-Proxy auf dem Satelliten-Server gestartet. Dies bedeutet, dass der LDAP-Server von diesem Server aus erreichbar sein muss. Die Pool-PCs hingegen m\u00fcssen nicht direkt mit dem LDAP-Server kommunizieren k\u00f6nnen.",
+ "lang_ldapText2": "Zu diesem Zweck wird ein LDAP-Proxy auf dem Satellitenserver gestartet. Dies bedeutet, dass der LDAP-Server von diesem Server aus erreichbar sein muss. Die Pool-PCs hingegen m\u00fcssen nicht direkt mit dem LDAP-Server kommunizieren k\u00f6nnen.",
"lang_legend": "Legende",
"lang_listenPort": "Listen port",
"lang_listenPortInfo": "Der Port, auf dem der sshd lauscht. Der offizielle Standard ist 22.",
@@ -72,6 +74,7 @@
"lang_moduleConfiguration": "Konfigurationsmodule",
"lang_moduleName": "Modulname",
"lang_moduleTitle": "Titel",
+ "lang_mountOptionsNote": "Diese Einstellungen beziehen sich nur auf Linux und \u00e4hnliche Systeme (sowohl das MiniLinux als auch laufende VMs) und beeinflussen die Optionen, die beim Mounten des Verzeichnisses verwendet werden sollen. Sofern es im LDAP\/AD ein Nutzerattribut gibt, welches die passenden Optionen enth\u00e4lt, k\u00f6nnen Sie dieses hier angeben. Das Attribut wird dann vorrangig behandelt. Ist das Attribut leer oder nicht vorhanden, werden die Optionen verwendet, die Sie im Feld \"feste Mount-Optionen\" eingetragen haben. Sind beide Felder leer, werden verschiedene Optionen automatisch durchprobiert.",
"lang_name": "Name",
"lang_newConfiguration": "Neue Konfiguration",
"lang_newModule": "Neues Modul",
@@ -99,6 +102,7 @@
"lang_shareDomainNote": "Der Dom\u00e4nenname wird beim Einbinden des Home-Verzeichnisses dem Benutzernamen vorangestellt (DOMAIN\\user). Normalerweise wird der Dom\u00e4nenname automatisch ermittelt, er l\u00e4sst sich hiermit aber explizit \u00fcberschreiben.",
"lang_shareDownloads": "Downloads",
"lang_shareHomeDrive": "Home-Verzeichnis Buchstabe (Windows)",
+ "lang_shareHomeMountOpts": "Fest vorgegebene Mount-Optionen",
"lang_shareMapCreate": "Ordner auf dem Netzlaufwerk bei Bedarf anlegen",
"lang_shareMedia": "Eigene Musik, Videos, Bilder",
"lang_shareModeNote": "\"Nativer Modus mit Fallback auf VMware\" ist experimentell und kann dazu f\u00fchren, dass die VM in regelm\u00e4\u00dfigen Abst\u00e4nden H\u00e4nger hat.",
@@ -124,4 +128,4 @@
"lang_userDirectoryInfo1": "Optionale Angabe: Wenn die Clients f\u00fcr die Benutzer ein eigenes Verzeichnis (Homeverzeichnis, Benutzerverzeichnis) von einem Server einbinden sollen, geben Sie bitte hier das Format in UNC-Notation an, also z.B.",
"lang_userDirectoryInfo2": "%s ist dabei ein Platzhalter f\u00fcr den Login-Namen des Benutzers.",
"lang_userDirectoryInfo3": "Das Verzeichnis wird mit den gleichen Zugangsdaten eingebunden, die der Benutzer beim Login angibt. (D.h. kein Kerberos Support o.\u00e4.)"
-}
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/lang/en/permissions.json b/modules-available/sysconfig/lang/en/permissions.json
new file mode 100644
index 00000000..14757383
--- /dev/null
+++ b/modules-available/sysconfig/lang/en/permissions.json
@@ -0,0 +1,8 @@
+{
+ "config.assign": "Assign system configuration",
+ "config.edit": "Edit system configuration",
+ "config.view-list": "Show system configurations",
+ "module.download": "Download configuration module",
+ "module.edit": "Edit configuration module",
+ "module.view-list": "Show configuration modules"
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/lang/en/template-tags.json b/modules-available/sysconfig/lang/en/template-tags.json
index 5a73c254..fb02cf42 100644
--- a/modules-available/sysconfig/lang/en/template-tags.json
+++ b/modules-available/sysconfig/lang/en/template-tags.json
@@ -47,17 +47,19 @@
"lang_fixNumeric": "Numeric account names have to be prefixed by 's'",
"lang_fixNumericDescription": "If enabled, users with account names that consist entirely of digits have to prefix their user id by 's' when logging in. This is required with the old login manager (KDM) to prevent crashes. The new lightdm-based login manager will accept numeric account names, so you can leave this option disabled. If your organization doesn't have any numeric account names, this option will have no effect.",
"lang_folderRedirection": "Folder Redirection",
+ "lang_genUid": "Generate uid numbers",
+ "lang_genUidDescription": "When selected, the satellite server will generate numeric IDs for the users, instead of extracting them from AD\/LDAP.",
"lang_generateModule": "Generating module",
"lang_handlingNotes": "Here you can configure how network shares (like the user's home directory) are mapped inside the VM. Old Versions of bwLehrpool used the VMware Shared Folder technique, which could cause problems with certain file servers. The new \"native mode\" works much better, but on Windows guests, it requires that you (1) use an smb\/cifs file server (Windows Server, Linux with Samba) and (2) have openslx.exe setup to autorun in the VM (this is already configured for bwLehrpool templates).",
"lang_helpHomeAttrHead": "Name of the home directory attribute",
"lang_helpHomeAttrText": "Here you can specify the name of the attribute on the Active Directory that contains the path of the home directory server. Usually this is \"homeDirectory\". If you leave this blank, the wiszard will try to determine the attribute name automatically. If home directories don't work, check the client log (Status->Client log) and the LDAP proxy log (Status->Server status).",
"lang_helpModuleConfiguration": "Configuration modules are the building blocks from which a system configuration is created. Here you can create both generic modules by a wizard, as well as create completely custom modules (advanced Linux knowledge required).",
"lang_helpSystemConfiguration": "The fundamental localization of the bwLehrpool system is done through a system configuration. These include aspects such as the authentication method for users (eg Active Directory, LDAP), printer configuration, home directories, etc. A system configuration is composed of one or more configuration modules, which can be managed in the panel next to this one.",
- "lang_homeAttr": "Home attribute",
"lang_homeAttributeExplanation": "Please select the attribute which holds the user's home directory.",
"lang_homeFallback": "Home fallback",
"lang_homedirHandling": "(Home) directory handling",
"lang_inheritFromParentLoc": "Inherit from parent location",
+ "lang_ldapAttrMountOpts": "LDAP attribute containing mount options",
"lang_ldapStarted": "The LDAP proxy has been launched",
"lang_ldapText1": "Here you can create a configuration module to authenticate agains an LDAP server",
"lang_ldapText2": "An LDAP-Proxy will be launched on this server. This means the LDAP-Server must be reachable from it. The client PCs in the labs however don't have to be able to talk to the LDAP server \u2013 they will use the proxy running on this server.",
@@ -72,6 +74,7 @@
"lang_moduleConfiguration": "Module Configuration",
"lang_moduleName": "Module Name",
"lang_moduleTitle": "Title",
+ "lang_mountOptionsNote": "These settings are relevant for the MiniLinux and VMs containing non-Windows OSes. If you specify an LDAP user attribute, its contents will be used as mount options when mounting the user's home directory. If the attribute is not specified or its contents are empty, the mount attributes specified in the other field will be used. If you leave both fields empty, the clients will try to determine the options automatically.",
"lang_name": "Name",
"lang_newConfiguration": "New Configuration",
"lang_newModule": "New Module",
@@ -99,6 +102,7 @@
"lang_shareDomainNote": "The user name will be prefixed by the domain when trying to mount home directories (DOMAIN\\user). Usually this will be determined automatically, but you can always override it here.",
"lang_shareDownloads": "Downloads",
"lang_shareHomeDrive": "Home drive letter (Windows)",
+ "lang_shareHomeMountOpts": "Fixed mount options",
"lang_shareMapCreate": "Create folders on network share if they don't exist",
"lang_shareMedia": "My Music, Videos, Pictures",
"lang_shareModeNote": "\"Native mode with fallback\" is experimental and known to cause temporary freezes with some VMs. Use with care.",
@@ -124,4 +128,4 @@
"lang_userDirectoryInfo1": "Optional: If the clients should embed a separate directory (home directory, user directory) from a server for the user, please enter here the format in UNC notation, eg",
"lang_userDirectoryInfo2": "%s is a placeholder for the user's login name.",
"lang_userDirectoryInfo3": "The directory is loaded with the same credentials that the user specifies when login. (That is no Kerberos support, etc.)"
-}
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/page.inc.php b/modules-available/sysconfig/page.inc.php
index 30271514..515d432c 100644
--- a/modules-available/sysconfig/page.inc.php
+++ b/modules-available/sysconfig/page.inc.php
@@ -59,7 +59,7 @@ class Page_SysConfig extends Page
{
User::load();
- if (!User::hasPermission('superadmin')) {
+ if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
@@ -90,6 +90,7 @@ class Page_SysConfig extends Page
// Action: "addmodule" (upload new module)
if ($action === 'addmodule') {
+ User::assertPermission('module.edit');
$this->initAddModule();
AddModule_Base::preprocess();
}
@@ -97,18 +98,22 @@ class Page_SysConfig extends Page
if ($action === 'module') {
// Action: "delmodule" (delete module)
if (Request::post('del', 'no') !== 'no') {
+ User::assertPermission('module.edit');
$this->delModule();
}
if (Request::post('download', 'no') !== 'no') {
+ User::assertPermission('module.download');
$this->downloadModule();
}
if (Request::post('rebuild', 'no') !== 'no') {
+ User::assertPermission('module.edit');
$this->rebuildModule();
}
}
// Action: "addconfig" (compose config from one or more modules)
if ($action === 'addconfig') {
+ User::assertPermission('config.edit');
$this->initAddConfig();
AddConfig_Base::preprocess();
}
@@ -116,14 +121,17 @@ class Page_SysConfig extends Page
if ($action === 'config') {
// Action: "delconfig" (delete config)
if (Request::post('del', 'no') !== 'no') {
+ User::assertPermission('config.edit');
$this->delConfig();
}
// Action "activate" (set sysconfig as active)
if (Request::post('activate', 'no') !== 'no') {
+ User::assertPermission('config.assign', $this->currentLoc);
$this->activateConfig();
}
// Action "rebuild" (rebuild config.tgz from its modules)
if (Request::post('rebuild', 'no') !== 'no') {
+ User::assertPermission('config.edit');
$this->rebuildConfig();
}
}
@@ -141,15 +149,24 @@ class Page_SysConfig extends Page
$action = Request::any('action', 'list');
switch ($action) {
case 'addmodule':
+ User::assertPermission('module.edit');
AddModule_Base::render();
return;
case 'addconfig':
+ User::assertPermission('config.edit');
AddConfig_Base::render();
return;
case 'list':
+ $pMods = User::hasPermission('module.view-list');
+ $pConfs = User::hasPermission('config.view-list');
+ if (!($pMods || $pConfs)) {
+ User::assertPermission('config.view-list');
+ }
Render::openTag('div', array('class' => 'row'));
- $this->listConfigs();
- if ($this->currentLoc === 0) {
+ if ($pConfs) {
+ $this->listConfigs();
+ }
+ if ($this->currentLoc === 0 && $pMods) {
$this->listModules();
}
Render::closeTag('div');
@@ -159,6 +176,7 @@ class Page_SysConfig extends Page
Render::addTemplate('js'); // Make this js snippet a template so i18n works
return;
case 'module':
+ User::assertPermission('module.view-list');
$listid = Request::post('list');
if ($listid !== false) {
$this->listModuleContents($listid);
@@ -166,6 +184,7 @@ class Page_SysConfig extends Page
}
break;
case 'config':
+ User::assertPermission('config.view-list');
$listid = Request::post('list');
if ($listid !== false) {
$this->listConfigContents($listid);
@@ -238,13 +257,16 @@ class Page_SysConfig extends Page
'needrebuild' => ($row['status'] !== 'OK')
);
}
- Render::addTemplate('list-configs', array(
+ $data = array(
'locationid' => $this->currentLoc,
'locationname' => $locationName,
'havelocations' => Module::isAvailable('locations'),
'configs' => $configs,
'inheritConfig' => !$hasDefault,
- ));
+ );
+ Permission::addGlobalTags($data['perms'], null, ['config.edit']);
+ Permission::addGlobalTags($data['perms'], $this->currentLoc, ['config.assign']);
+ Render::addTemplate('list-configs', $data);
}
private function listModules()
@@ -254,10 +276,12 @@ class Page_SysConfig extends Page
$types = array_map(function ($mod) { return $mod->moduleType(); }, $modules);
$titles = array_map(function ($mod) { return $mod->title(); }, $modules);
array_multisort($types, SORT_ASC, $titles, SORT_ASC, $modules);
- Render::addTemplate('list-modules', array(
+ $data = array(
'modules' => $modules,
'havemodules' => (count($modules) > 0)
- ));
+ );
+ Permission::addGlobalTags($data['perms'], null, ['module.edit', 'module.download']);
+ Render::addTemplate('list-modules', $data);
}
private function listModuleContents($moduleid)
@@ -401,12 +425,12 @@ class Page_SysConfig extends Page
$task = Taskmanager::submit('DeleteFile', array(
'file' => $row['filepath']
));
- if (isset($task['statusCode']) && $task['statusCode'] === TASK_WAITING) {
+ if (isset($task['statusCode']) && $task['statusCode'] === Taskmanager::TASK_WAITING) {
$task = Taskmanager::waitComplete($task['id']);
}
- if (!isset($task['statusCode']) || $task['statusCode'] === TASK_ERROR) {
+ if (!isset($task['statusCode']) || $task['statusCode'] === Taskmanager::TASK_ERROR) {
Message::addWarning('main.task-error', $task['data']['error']);
- } elseif ($task['statusCode'] === TASK_FINISHED) {
+ } elseif ($task['statusCode'] === Taskmanager::TASK_FINISHED) {
Message::addSuccess('module-deleted', $row['title']);
}
Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleid));
diff --git a/modules-available/sysconfig/permissions/permissions.json b/modules-available/sysconfig/permissions/permissions.json
new file mode 100644
index 00000000..08321c50
--- /dev/null
+++ b/modules-available/sysconfig/permissions/permissions.json
@@ -0,0 +1,20 @@
+{
+ "config.view-list": {
+ "location-aware": false
+ },
+ "config.assign": {
+ "location-aware": true
+ },
+ "config.edit": {
+ "location-aware": false
+ },
+ "module.view-list": {
+ "location-aware": false
+ },
+ "module.edit": {
+ "location-aware": false
+ },
+ "module.download": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/templates/ad-selfsearch.html b/modules-available/sysconfig/templates/ad-selfsearch.html
index 64e181b2..e6a19468 100644
--- a/modules-available/sysconfig/templates/ad-selfsearch.html
+++ b/modules-available/sysconfig/templates/ad-selfsearch.html
@@ -43,6 +43,7 @@
<input type="hidden" name="mapping[{{field}}]" value="{{value}}">
{{/mapping}}
<input name="fixnumeric" value="{{fixnumeric}}" type="hidden">
+ <input name="genuid" value="{{genuid}}" type="hidden">
<button type="submit" class="btn btn-primary">&laquo; {{lang_back}}</button>
</form>
</div>
@@ -67,6 +68,7 @@
<input type="hidden" name="mapping[{{field}}]" value="{{value}}">
{{/mapping}}
<input name="fixnumeric" value="{{fixnumeric}}" type="hidden">
+ <input name="genuid" value="{{genuid}}" type="hidden">
<input name="fingerprint" value="{{fingerprint}}" type="hidden">
<button id="nextbutton" type="submit" class="btn btn-primary" style="display:none">{{lang_skip}} &raquo;</button>
</form>
diff --git a/modules-available/sysconfig/templates/ad-start.html b/modules-available/sysconfig/templates/ad-start.html
index 7f211343..274473ff 100644
--- a/modules-available/sysconfig/templates/ad-start.html
+++ b/modules-available/sysconfig/templates/ad-start.html
@@ -67,6 +67,16 @@
<br>
<div>
<div class="checkbox">
+ <input id="num-cb" type="checkbox" name="genuid" {{#genuid}}checked{{/genuid}}>
+ <label for="num-cb"><b>{{lang_genUid}}</b></label>
+ </div>
+ <div>
+ <i>{{lang_genUidDescription}}</i>
+ </div>
+ </div>
+ <br>
+ <div>
+ <div class="checkbox">
<input id="num-cb" type="checkbox" name="fixnumeric" {{#fixnumeric}}checked{{/fixnumeric}}>
<label for="num-cb"><b>{{lang_fixNumeric}}</b></label>
</div>
diff --git a/modules-available/sysconfig/templates/ad_ldap-checkconnection.html b/modules-available/sysconfig/templates/ad_ldap-checkconnection.html
index 630da398..e686c29f 100644
--- a/modules-available/sysconfig/templates/ad_ldap-checkconnection.html
+++ b/modules-available/sysconfig/templates/ad_ldap-checkconnection.html
@@ -31,6 +31,7 @@
{{/mapping}}
<input name="fixnumeric" value="{{fixnumeric}}" type="hidden">
+ <input name="genuid" value="{{genuid}}" type="hidden">
<button type="submit" class="btn btn-primary">&laquo; {{lang_back}}</button>
</form>
</div>
@@ -55,6 +56,7 @@
<input type="hidden" name="mapping[{{field}}]" value="{{value}}">
{{/mapping}}
<input name="fixnumeric" value="{{fixnumeric}}" type="hidden">
+ <input name="genuid" value="{{genuid}}" type="hidden">
<input name="originalbinddn" value="{{binddn}}" type="hidden">
<button id="nextbutton" type="submit" class="btn btn-primary" style="display:none">{{lang_next}} &raquo;</button>
</form>
diff --git a/modules-available/sysconfig/templates/ad_ldap-checkcredentials.html b/modules-available/sysconfig/templates/ad_ldap-checkcredentials.html
index 4f822a9b..d698d994 100644
--- a/modules-available/sysconfig/templates/ad_ldap-checkcredentials.html
+++ b/modules-available/sysconfig/templates/ad_ldap-checkcredentials.html
@@ -26,6 +26,7 @@
<input type="hidden" name="mapping[{{field}}]" value="{{value}}">
{{/mapping}}
<input name="fixnumeric" value="{{fixnumeric}}" type="hidden">
+ <input name="genuid" value="{{genuid}}" type="hidden">
<button type="submit" class="btn btn-primary">&laquo; {{lang_back}}</button>
</form>
</div>
@@ -49,6 +50,7 @@
<input type="hidden" name="mapping[{{field}}]" value="{{value}}">
{{/mapping}}
<input name="fixnumeric" value="{{fixnumeric}}" type="hidden">
+ <input name="genuid" value="{{genuid}}" type="hidden">
<input name="fingerprint" value="{{fingerprint}}" type="hidden">
<input name="originalbinddn" value="{{binddn}}" type="hidden">
<button id="nextbutton" type="submit" class="btn btn-primary" style="display:none">{{lang_skip}} &raquo;</button>
diff --git a/modules-available/sysconfig/templates/ad_ldap-homedir.html b/modules-available/sysconfig/templates/ad_ldap-homedir.html
index ad543594..e4fbf380 100644
--- a/modules-available/sysconfig/templates/ad_ldap-homedir.html
+++ b/modules-available/sysconfig/templates/ad_ldap-homedir.html
@@ -18,6 +18,7 @@
<input type="hidden" name="mapping[{{field}}]" value="{{value}}">
{{/mapping}}
<input name="fixnumeric" value="{{fixnumeric}}" type="hidden">
+ <input name="genuid" value="{{genuid}}" type="hidden">
<input name="fingerprint" value="{{fingerprint}}" type="hidden">
<div class="slx-bold">{{lang_credentialPassing}}</div>
@@ -61,6 +62,20 @@
<p><i>{{lang_driveLetterNote}}</i></p>
</div>
</div>
+ <div class="form-group row">
+ <label for="inputldapAttrMountOpts" class="control-label col-xs-4">{{lang_ldapAttrMountOpts}}</label>
+ <div class="col-xs-8">
+ <input type="text" class="form-control" id="inputldapAttrMountOpts" name="ldapAttrMountOpts" value="{{ldapAttrMountOpts}}">
+ </div>
+ </div>
+ <div class="form-group row">
+ <label for="inputshareHomeMountOpts" class="control-label col-xs-4">{{lang_shareHomeMountOpts}}</label>
+ <div class="col-xs-8">
+ <input type="text" class="form-control" id="inputshareHomeMountOpts" name="shareHomeMountOpts" value="{{shareHomeMountOpts}}"
+ placeholder="vers=3.0,forceuid,forcegid,nounix,file_mode=0700,dir_mode=0700,noacl,nobrl">
+ <p><i>{{lang_mountOptionsNote}}</i></p>
+ </div>
+ </div>
<hr>
<div class="slx-bold">{{lang_folderRedirection}}</div>
diff --git a/modules-available/sysconfig/templates/ldap-start.html b/modules-available/sysconfig/templates/ldap-start.html
index 940316b9..b3495741 100644
--- a/modules-available/sysconfig/templates/ldap-start.html
+++ b/modules-available/sysconfig/templates/ldap-start.html
@@ -68,6 +68,16 @@
<br>
<div>
<div class="checkbox">
+ <input id="num-cb" type="checkbox" name="genuid" {{#genuid}}checked{{/genuid}}>
+ <label for="num-cb"><b>{{lang_genUid}}</b></label>
+ </div>
+ <div>
+ <i>{{lang_genUidDescription}}</i>
+ </div>
+ </div>
+ <br>
+ <div>
+ <div class="checkbox">
<input id="num-cb" type="checkbox" name="fixnumeric" {{#fixnumeric}}checked{{/fixnumeric}}>
<label for="num-cb"><b>{{lang_fixNumeric}}</b></label>
</div>
diff --git a/modules-available/sysconfig/templates/list-configs.html b/modules-available/sysconfig/templates/list-configs.html
index 205317b8..4db7b9b2 100644
--- a/modules-available/sysconfig/templates/list-configs.html
+++ b/modules-available/sysconfig/templates/list-configs.html
@@ -26,7 +26,7 @@
</td>
<td>
{{^current}}
- <button class="btn btn-primary btn-xs" name="activate" value="{{configid}}">
+ <button class="btn btn-primary btn-xs" name="activate" value="{{configid}}" {{perms.config.assign.disabled}}>
<span class="glyphicon glyphicon-flag"></span>
{{lang_activate}}
</button>
@@ -54,13 +54,22 @@
{{^needrebuild}}
class="refconf btn btn-default btn-xs"
{{/needrebuild}}
- name="rebuild" value="{{configid}}" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></button>
+ name="rebuild" value="{{configid}}" title="{{lang_rebuild}}"
+ {{perms.config.edit.disabled}}>
+ <span class="glyphicon glyphicon-refresh"></span>
+ </button>
{{/locationid}}
</td>
<td class="text-nowrap">
{{^locationid}}
- <a class="btn btn-success btn-xs" href="?do=SysConfig&amp;action=addconfig&amp;edit={{configid}}" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></a>
- <button class="btn btn-danger btn-xs confirm-delete" name="del" value="{{configid}}" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></button>
+ <a class="btn btn-success btn-xs {{perms.config.edit.disabled}}"
+ href="?do=SysConfig&amp;action=addconfig&amp;edit={{configid}}" title="{{lang_edit}}">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ <button class="btn btn-danger btn-xs confirm-delete" name="del" value="{{configid}}"
+ title="{{lang_delete}}" {{perms.config.edit.disabled}}>
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
{{/locationid}}
</td>
</tr>
@@ -101,7 +110,9 @@
</div>
{{^locationid}}
<div class="panel-footer text-right">
- <a class="btn btn-primary" href="?do=SysConfig&amp;action=addconfig">{{lang_newConfiguration}}</a>
+ <a class="btn btn-primary {{perms.config.edit.disabled}}" href="?do=SysConfig&amp;action=addconfig">
+ {{lang_newConfiguration}}
+ </a>
</div>
{{/locationid}}
</div>
diff --git a/modules-available/sysconfig/templates/list-modules.html b/modules-available/sysconfig/templates/list-modules.html
index a55253ec..c657eae8 100644
--- a/modules-available/sysconfig/templates/list-modules.html
+++ b/modules-available/sysconfig/templates/list-modules.html
@@ -16,7 +16,10 @@
<td class="text-nowrap">
{{#allowDownload}}
<button class="btn btn-default btn-xs" name="list" value="{{id}}" title="{{lang_show}}"><span class="glyphicon glyphicon-eye-open"></span></button>
- <button class="btn btn-default btn-xs" name="download" value="{{id}}" title="{{lang_download}}"><span class="glyphicon glyphicon-download-alt"></span></button>
+ <button class="btn btn-default btn-xs" name="download" value="{{id}}"
+ title="{{lang_download}}" {{perms.module.download.disabled}}>
+ <span class="glyphicon glyphicon-download-alt"></span>
+ </button>
{{/allowDownload}}
</td>
<td class="text-nowrap">
@@ -27,9 +30,18 @@
{{^needRebuild}}
class="refmod btn btn-default btn-xs"
{{/needRebuild}}
- name="rebuild" value="{{id}}" title="{{lang_rebuild}}"><span class="glyphicon glyphicon-refresh"></span></button>
- <a class="btn btn-success btn-xs" href="?do=SysConfig&amp;action=addmodule&amp;step={{moduleType}}_Start&amp;edit={{id}}" title="{{lang_edit}}"><span class="glyphicon glyphicon-edit"></span></a>
- <button class="btn btn-danger btn-xs confirm-delete" name="del" value="{{id}}" title="{{lang_delete}}"><span class="glyphicon glyphicon-trash"></span></button>
+ name="rebuild" value="{{id}}" title="{{lang_rebuild}}" {{perms.module.edit.disabled}}>
+ <span class="glyphicon glyphicon-refresh"></span>
+ </button>
+ <a class="btn btn-success btn-xs {{perms.module.edit.disabled}}"
+ href="?do=SysConfig&amp;action=addmodule&amp;step={{moduleType}}_Start&amp;edit={{id}}"
+ title="{{lang_edit}}">
+ <span class="glyphicon glyphicon-edit"></span>
+ </a>
+ <button class="btn btn-danger btn-xs confirm-delete" name="del" value="{{id}}"
+ title="{{lang_delete}}" {{perms.module.edit.disabled}}>
+ <span class="glyphicon glyphicon-trash"></span>
+ </button>
</td>
</tr>
{{/modules}}
@@ -40,7 +52,9 @@
</form>
</div>
<div class="panel-footer text-right">
- <a class="btn btn-primary" href="?do=SysConfig&amp;action=addmodule">{{lang_newModule}}</a>
+ <a class="btn btn-primary {{perms.module.edit.disabled}}" href="?do=SysConfig&amp;action=addmodule">
+ {{lang_newModule}}
+ </a>
</div>
</div>
diff --git a/modules-available/sysconfig/templates/sshconfig-start.html b/modules-available/sysconfig/templates/sshconfig-start.html
index c0b4b379..a2339b0f 100644
--- a/modules-available/sysconfig/templates/sshconfig-start.html
+++ b/modules-available/sysconfig/templates/sshconfig-start.html
@@ -21,7 +21,7 @@
</div>
<div class="form-group">
<label for="port">{{lang_listenPort}}</label>
- <input class="form-control" type="text" name="listenPort" value="{{listenPort}}" id="port" pattern="\d+">
+ <input class="form-control" type="text" name="listenPort" value="{{listenPort}}" id="port" pattern="\d+" placeholder="22">
<i>{{lang_listenPortInfo}}</i>
</div>
<hr/>
diff --git a/modules-available/sysconfignew/config.json b/modules-available/sysconfignew/config.json
index 28d71577..6c7b7146 100644
--- a/modules-available/sysconfignew/config.json
+++ b/modules-available/sysconfignew/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.settings-client"
-}
+ "category": "main.settings-client"
+} \ No newline at end of file
diff --git a/modules-available/syslog/api.inc.php b/modules-available/syslog/api.inc.php
index 18c42c31..945f9d09 100644
--- a/modules-available/syslog/api.inc.php
+++ b/modules-available/syslog/api.inc.php
@@ -1,5 +1,44 @@
<?php
+// Check for user data export
+if (($user = Request::post('export-user', false, 'string')) !== false) {
+ User::load();
+ User::assertPermission('export-user-data', null, '?do=syslog');
+ if (!Util::verifyToken()) {
+ die('Invalid Token');
+ }
+ $puser = preg_quote($user);
+ $exp = "$puser logged|^\[$puser\]";
+ Header('Content-Type: text/plain; charset=utf-8');
+ Header('Content-Disposition: attachment; filename=bwlehrpool-export-' .Util::sanitizeFilename($user) . '-' . date('Y-m-d') . '.txt');
+ $srcs = [];
+ $srcs[] = ['res' => Database::simpleQuery("SELECT dateline, logtypeid AS typeid, clientip, description FROM clientlog
+ WHERE description REGEXP :exp
+ ORDER BY dateline ASC", ['exp' => $exp])];
+ if (Module::get('statistics') !== false) {
+ $srcs[] = ['res' => Database::simpleQuery("SELECT dateline, typeid, clientip, data AS description FROM statistic
+ WHERE username = :user
+ ORDER BY dateline ASC", ['user' => $user])];
+ }
+ echo "# Begin log\n";
+ for (;;) {
+ unset($best);
+ foreach ($srcs as &$src) {
+ if (!isset($src['row'])) {
+ $src['row'] = $src['res']->fetch(PDO::FETCH_ASSOC);
+ }
+ if ($src['row'] !== false && (!isset($best) || $src['row']['dateline'] < $best['dateline'])) {
+ $best =& $src['row'];
+ }
+ }
+ if (!isset($best))
+ break;
+ echo date('Y-m-d H:i:s', $best['dateline']), "\t", $best['typeid'], "\t", $best['clientip'], "\t", $best['description'], "\n";
+ $best = null; // so we repopulate on next iteration
+ }
+ die("# End log\n");
+}
+
if (empty($_POST['type'])) die('Missing options.');
$type = mb_strtolower($_POST['type']);
diff --git a/modules-available/syslog/config.json b/modules-available/syslog/config.json
index 2b718a8e..691bd4df 100644
--- a/modules-available/syslog/config.json
+++ b/modules-available/syslog/config.json
@@ -1,4 +1,6 @@
{
- "category":"main.status",
- "dependencies":["js_selectize"]
-}
+ "category": "main.status",
+ "dependencies": [
+ "js_selectize"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/syslog/hooks/cron.inc.php b/modules-available/syslog/hooks/cron.inc.php
index bae882a9..62516648 100644
--- a/modules-available/syslog/hooks/cron.inc.php
+++ b/modules-available/syslog/hooks/cron.inc.php
@@ -1,7 +1,28 @@
<?php
if (mt_rand(1, 10) === 1) {
+ // Prune old entries
Database::exec("DELETE FROM clientlog WHERE (UNIX_TIMESTAMP() - 86400 * 190) > dateline");
+ // Anonymize if requested
+ $days = Property::get('syslog.anon-days', 0);
+ if ($days > 0) {
+ $cutoff = time() - ($days * 86400);
+ Database::exec("UPDATE clientlog SET description = '[root] User logged in'
+ WHERE $cutoff > dateline AND logtypeid = 'session-open' AND description NOT LIKE '[root] User %'");
+ Database::exec("UPDATE clientlog SET description = '[root] User logged out'
+ WHERE $cutoff > dateline AND logtypeid = 'session-close' AND description NOT LIKE '[root] User %'");
+ Database::exec("UPDATE clientlog SET description = '-', extra = ''
+ WHERE $cutoff > dateline AND description NOT LIKE '-'
+ AND logtypeid NOT IN ('session-open', 'session-close', 'idleaction-busy', 'partition-temp',
+ 'partition-swap', 'smartctl-realloc', 'vmware-netifup', 'vmware-insmod', 'firewall-script-apply',
+ 'mount-vm-tmp-fail')");
+ if (Module::get('statistics') !== false) {
+ Database::exec("UPDATE statistic SET username = 'anonymous'
+ WHERE $cutoff > dateline AND username NOT LIKE 'anonymous' AND username NOT LIKE ''");
+ Database::exec("UPDATE machine SET currentuser = NULL
+ WHERE $cutoff > lastseen AND currentuser IS NOT NULL");
+ }
+ }
if (mt_rand(1, 100) === 1) {
Database::exec("OPTIMIZE TABLE clientlog");
}
diff --git a/modules-available/syslog/lang/de/messages.json b/modules-available/syslog/lang/de/messages.json
new file mode 100644
index 00000000..eec31c2f
--- /dev/null
+++ b/modules-available/syslog/lang/de/messages.json
@@ -0,0 +1,4 @@
+{
+ "anon-days-out-of-range": "Tage muss zwischen 0 und 180 liegen (war {{0}})",
+ "anon-days-saved": "Anonymisierungszeitraum gespeichert"
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/de/permissions.json b/modules-available/syslog/lang/de/permissions.json
new file mode 100644
index 00000000..dcd96ae1
--- /dev/null
+++ b/modules-available/syslog/lang/de/permissions.json
@@ -0,0 +1,4 @@
+{
+ "configure-anonymization": "Einstellen, nach wie vielen Tagen die Nutzernamen in den Logs entfernt werden.",
+ "view": "Client Log anschauen."
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/de/template-tags.json b/modules-available/syslog/lang/de/template-tags.json
index c8b2bb45..c00d619a 100644
--- a/modules-available/syslog/lang/de/template-tags.json
+++ b/modules-available/syslog/lang/de/template-tags.json
@@ -1,11 +1,16 @@
{
+ "lang_anonDaysDescription": "Nach wie vielen Tagen sollen Logeintr\u00e4ge anonymisiert werden? Auf 0 setzen, um Funktion zu deaktivieren.",
+ "lang_applyFilter": "Filter anwenden",
"lang_client": "Client",
"lang_clientLog": "Client Log",
"lang_details": "Details",
"lang_event": "Ereignis",
+ "lang_export": "Exportieren",
+ "lang_exportUserDesc": "Mit dieser Funktion k\u00f6nnen Sie alle in der Datenbank vorhandenen Datens\u00e4tze zu einem bestimmten Benutzer exportieren. Bitte geben Sie den Benutzernamen genau so ein, wie ihn der Nutzer beim Login am Client angeben muss.",
"lang_filter": "Filter",
- "lang_go": "Go",
"lang_not": "not",
- "lang_when": "Wann",
- "lang_applyFilter": "Filter anwenden"
+ "lang_settings": "Einstellungen",
+ "lang_userExport": "Nutzer-Export",
+ "lang_userLogin": "Benutzer-Login",
+ "lang_when": "Wann"
} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/messages.json b/modules-available/syslog/lang/en/messages.json
new file mode 100644
index 00000000..5578d7b9
--- /dev/null
+++ b/modules-available/syslog/lang/en/messages.json
@@ -0,0 +1,4 @@
+{
+ "anon-days-out-of-range": "Days have to be between 0 and 180 (was {{0}})",
+ "anon-days-saved": "Anonymization delay saved"
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/permissions.json b/modules-available/syslog/lang/en/permissions.json
new file mode 100644
index 00000000..26ea4448
--- /dev/null
+++ b/modules-available/syslog/lang/en/permissions.json
@@ -0,0 +1,4 @@
+{
+ "configure-anonymization": "Configure after how many days any usernames will be removed from log files.",
+ "view": "View client log."
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/template-tags.json b/modules-available/syslog/lang/en/template-tags.json
index 7dae52d9..24e9aaa1 100644
--- a/modules-available/syslog/lang/en/template-tags.json
+++ b/modules-available/syslog/lang/en/template-tags.json
@@ -1,11 +1,16 @@
{
+ "lang_anonDaysDescription": "After how many days should log messages be anonymized? Set to 0 to disable this feature.",
+ "lang_applyFilter": "Apply Filter",
"lang_client": "Client",
"lang_clientLog": "Client Log",
"lang_details": "Details",
"lang_event": "Event",
+ "lang_export": "Export",
+ "lang_exportUserDesc": "This exports all data from the database relating to the given user login. Please specify the user name exactly the way they would provide it when logging in on a client.",
"lang_filter": "Filter",
- "lang_go": "Go",
"lang_not": "not",
- "lang_when": "When",
- "lang_applyFilter": "Apply Filter"
+ "lang_settings": "Settings",
+ "lang_userExport": "User export",
+ "lang_userLogin": "User login",
+ "lang_when": "When"
} \ No newline at end of file
diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php
index 153b591f..6c1a0a16 100644
--- a/modules-available/syslog/page.inc.php
+++ b/modules-available/syslog/page.inc.php
@@ -3,6 +3,9 @@
class Page_SysLog extends Page
{
+ const PROP_ANON_DAYS = 'syslog.anon-days'; // Copy in cronjob
+
+
protected function doPreprocess()
{
User::load();
@@ -11,10 +14,31 @@ class Page_SysLog extends Page
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
+
+ if (($days = Request::post('anondays', false, 'int')) !== false) {
+ User::assertPermission('configure-anonymization', NULL,'?do=syslog');
+ if ($days < 0 || $days > 180) {
+ Message::addError('anon-days-out-of-range', $days);
+ } else {
+ Property::set(self::PROP_ANON_DAYS, $days);
+ Message::addSuccess('anon-days-saved');
+ }
+ Util::redirect('?do=syslog');
+ }
+ User::assertPermission('*');
}
protected function doRender()
{
+ $data = ['anondays' => Property::get(self::PROP_ANON_DAYS, 0)];
+ Permission::addGlobalTags($data['perms'], NULL, ['configure-anonymization', 'export-user-data']);
+ Render::addTemplate("heading", $data);
+
+ if (!User::hasPermission("view")) {
+ Message::addError('main.no-permission');
+ return;
+ }
+
$cutoff = strtotime('-1 month');
$res = Database::simpleQuery("SELECT logtypeid, Count(*) AS counter FROM clientlog WHERE dateline > $cutoff GROUP BY logtypeid ORDER BY counter ASC");
$types = array();
@@ -57,9 +81,22 @@ class Page_SysLog extends Page
$whereClause .= "machineuuid='" . preg_replace('/[^0-9a-zA-Z\-]/', '', Request::get('machineuuid', '', 'string')) . "'";
}
+
+ $allowedLocations = User::getAllowedLocations("view");
+ $joinClause = "";
+ if (!in_array(0, $allowedLocations)) {
+ $joinClause = "INNER JOIN machine USING (machineuuid)";
+ if (empty($whereClause))
+ $whereClause .= ' WHERE ';
+ else
+ $whereClause .= ' AND ';
+
+ $whereClause .= 'locationid IN (:allowedLocations)';
+ }
+
$lines = array();
- $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, machineuuid, description, extra FROM clientlog $whereClause ORDER BY logid DESC", 50);
- $res = $paginate->exec();
+ $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientlog.clientip, clientlog.machineuuid, description, extra FROM clientlog $joinClause $whereClause ORDER BY logid DESC", 50);
+ $res = $paginate->exec(array("allowedLocations" => $allowedLocations));
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$row['date'] = Util::prettyTime($row['dateline']);
$row['icon'] = $this->eventToIconName($row['logtypeid']);
diff --git a/modules-available/syslog/permissions/permissions.json b/modules-available/syslog/permissions/permissions.json
new file mode 100644
index 00000000..1f2373d4
--- /dev/null
+++ b/modules-available/syslog/permissions/permissions.json
@@ -0,0 +1,11 @@
+{
+ "view": {
+ "location-aware": true
+ },
+ "configure-anonymization": {
+ "location-aware": false
+ },
+ "export-user-data": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/syslog/templates/heading.html b/modules-available/syslog/templates/heading.html
new file mode 100644
index 00000000..8dd3d440
--- /dev/null
+++ b/modules-available/syslog/templates/heading.html
@@ -0,0 +1,68 @@
+<div class="page-header">
+ <span class="buttonbar pull-right">
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-export" {{perms.export-user-data.disabled}}>
+ <span class="glyphicon glyphicon-export"></span>
+ {{lang_userExport}}
+ </button>
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-settings">
+ <span class="glyphicon glyphicon-cog"></span> {{lang_settings}}
+ </button>
+ </span>
+
+ <div id="modal-settings" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form method="post" action="?do=syslog">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">&times;</button>
+ <h4 class="modal-title"><b>{{lang_settings}}</b></h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_anonDaysDescription}}</p>
+ <input {{perms.configure-anonymization.disabled}} class="form-control" type="number" name="anondays"
+ value="{{anondays}}" min="0" max="180">
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button {{perms.configure-anonymization.disabled}} type="submit"
+ class="btn btn-primary">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ </form>
+ </div>
+
+ </div>
+ </div>
+
+ <div id="modal-export" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form method="post" action="api.php?do=syslog">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">&times;</button>
+ <h4 class="modal-title"><b>{{lang_userExport}}</b></h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_exportUserDesc}}</p>
+ <label for="export-user-name">{{lang_userLogin}}</label>
+ <input id="export-user-name" type="text" name="export-user" class="form-control" style="width:100%">
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-primary">
+ <span class="glyphicon glyphicon-export"></span>
+ {{lang_export}}
+ </button>
+ </div>
+ </form>
+ </div>
+
+ </div>
+ </div>
+
+ <h1>{{lang_clientLog}}</h1>
+</div> \ No newline at end of file
diff --git a/modules-available/syslog/templates/page-syslog.html b/modules-available/syslog/templates/page-syslog.html
index d4709456..9d05d434 100644
--- a/modules-available/syslog/templates/page-syslog.html
+++ b/modules-available/syslog/templates/page-syslog.html
@@ -1,4 +1,3 @@
-<h1>{{lang_clientLog}}</h1>
<style type="text/css">
.selectize-dropdown {
max-width: 500px;
diff --git a/modules-available/systemstatus/config.json b/modules-available/systemstatus/config.json
index 3c2efce7..cf774d1b 100644
--- a/modules-available/systemstatus/config.json
+++ b/modules-available/systemstatus/config.json
@@ -1,4 +1,6 @@
{
- "category":"main.status",
- "dependencies": [ "js_circles" ]
-}
+ "category": "main.status",
+ "dependencies": [
+ "js_circles"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/systemstatus/lang/de/permissions.json b/modules-available/systemstatus/lang/de/permissions.json
new file mode 100644
index 00000000..a3041fbc
--- /dev/null
+++ b/modules-available/systemstatus/lang/de/permissions.json
@@ -0,0 +1,13 @@
+{
+ "serverreboot": "Server neustarten.",
+ "show.overview.addresses": "Zeige Adresskonfiguration auf \u00dcbersichtsseite.",
+ "show.overview.diskstat": "Zeige Speicherplatzwerte auf \u00dcbersichtsseite.",
+ "show.overview.dmsdusers": "Zeige dmsd-Werte auf \u00dcbersichtsseite.",
+ "show.overview.services": "Zeige Dienste auf \u00dcbersichtsseite.",
+ "show.overview.systeminfo": "Zeige Systemwerte auf \u00dcbersichtsseite.",
+ "tab.dmsdlog": "Zugriff auf bwLehrpool-Suite-Server Statusausgabe.",
+ "tab.ldadplog": "Zugriff auf LDAP\/AD-Proxy Logs.",
+ "tab.lighttpdlog": "Zugriff auf Webserver-Logs.",
+ "tab.netstat": "Zeige Ausgabe von netstat.",
+ "tab.pslist": "Zeige Prozessliste."
+} \ No newline at end of file
diff --git a/modules-available/systemstatus/lang/de/template-tags.json b/modules-available/systemstatus/lang/de/template-tags.json
index 89066257..eeb75f9a 100644
--- a/modules-available/systemstatus/lang/de/template-tags.json
+++ b/modules-available/systemstatus/lang/de/template-tags.json
@@ -26,7 +26,7 @@
"lang_storeMissingExpected": "VM-Store nicht eingebunden. Erwartet:",
"lang_storeNotConfigured": "Kein VM-Store konfiguriert!",
"lang_swapUsage": "swap-Nutzung",
- "lang_swapWarning": "Es wird swap-Speicher genutzt. Dies kann ein Hinweis darauf sein, dass dem Satelliten-Server zu wenig physikalischer Speicher zur Verf\u00fcgung steht. Im Falle von Performance-Problemen oder Instabilit\u00e4t des Servers sollten Sie erw\u00e4gen, den Server mit mehr RAM auszustatten.",
+ "lang_swapWarning": "Es wird swap-Speicher genutzt. Dies kann ein Hinweis darauf sein, dass dem Satellitenserver zu wenig physikalischer Speicher zur Verf\u00fcgung steht. Im Falle von Performance-Problemen oder Instabilit\u00e4t des Servers sollten Sie erw\u00e4gen, den Server mit mehr RAM auszustatten.",
"lang_system": "System",
"lang_systemPartition": "Systempartition",
"lang_systemStoreError": "Fehler beim Ermitteln des verf\u00fcgbaren Systemspeichers",
diff --git a/modules-available/systemstatus/lang/en/permissions.json b/modules-available/systemstatus/lang/en/permissions.json
new file mode 100644
index 00000000..879fa882
--- /dev/null
+++ b/modules-available/systemstatus/lang/en/permissions.json
@@ -0,0 +1,13 @@
+{
+ "serverreboot": "Reboot server.",
+ "show.overview.addresses": "Show addresses on overview page.",
+ "show.overview.diskstat": "Show diskstats on overview page.",
+ "show.overview.dmsdusers": "Show dmsd-stats on overview page.",
+ "show.overview.services": "Show services on overview page.",
+ "show.overview.systeminfo": "Show systeminfo on overview page.",
+ "tab.dmsdlog": "Show bwLehrpool-Suite status.",
+ "tab.ldadplog": "Show LDAP\/AD proxy logs.",
+ "tab.lighttpdlog": "Show web server logs.",
+ "tab.netstat": "Show output of netstat.",
+ "tab.pslist": "Show process list."
+} \ No newline at end of file
diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php
index 8a0e5f87..04423eaf 100644
--- a/modules-available/systemstatus/page.inc.php
+++ b/modules-available/systemstatus/page.inc.php
@@ -15,8 +15,10 @@ class Page_SystemStatus extends Page
}
if (Request::post('action') === 'reboot') {
+ User::assertPermission("serverreboot");
$this->rebootTask = Taskmanager::submit('Reboot');
}
+ User::assertPermission('*');
}
protected function doRender()
@@ -30,9 +32,11 @@ class Page_SystemStatus extends Page
foreach ($tabs as $tab) {
$data['tabs'][] = array(
'type' => $tab,
- 'name' => Dictionary::translate('tab_' . $tab)
+ 'name' => Dictionary::translate('tab_' . $tab),
+ 'enabled' => User::hasPermission('tab.' . $tab),
);
}
+ Permission::addGlobalTags($data['perms'], null, ['serverreboot']);
Render::addTemplate('_page', $data);
}
@@ -54,6 +58,7 @@ class Page_SystemStatus extends Page
protected function ajaxDmsdUsers()
{
+ User::assertPermission("show.overview.dmsdusers");
$ret = Download::asStringPost('http://127.0.0.1:9080/status/fileserver', false, 2, $code);
$args = array();
if ($code != 200) {
@@ -75,6 +80,7 @@ class Page_SystemStatus extends Page
protected function ajaxDiskStat()
{
+ User::assertPermission("show.overview.diskstat");
$task = Taskmanager::submit('DiskStat');
if ($task === false)
return;
@@ -136,6 +142,7 @@ class Page_SystemStatus extends Page
protected function ajaxAddressList()
{
+ User::assertPermission("show.overview.addresses");
$task = Taskmanager::submit('LocalAddressesList');
if ($task === false)
return;
@@ -178,6 +185,7 @@ class Page_SystemStatus extends Page
protected function ajaxSystemInfo()
{
+ User::assertPermission("show.overview.systeminfo");
$cpuInfo = file_get_contents('/proc/cpuinfo');
$uptime = file_get_contents('/proc/uptime');
$cpuCount = preg_match_all('/\bprocessor\s/', $cpuInfo, $out);
@@ -201,7 +209,7 @@ class Page_SystemStatus extends Page
$data['swapTotal'] = Util::readableFileSize($info['SwapTotal'] * 1024);
$data['swapUsed'] = Util::readableFileSize(($info['SwapTotal'] - $info['SwapFree']) * 1024);
$data['swapPercent'] = 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100);
- $data['swapWarning'] = ($data['swapPercent'] > 50 || ($info['SwapTotal'] - $info['SwapFree']) > 200000);
+ $data['swapWarning'] = ($data['swapPercent'] > 50 || $info['SwapFree'] < 400000);
}
if (isset($info['CpuIdle']) && isset($info['CpuSystem']) && isset($info['CpuTotal'])) {
$data['cpuLoad'] = 100 - round(($info['CpuIdle'] / $info['CpuTotal']) * 100);
@@ -215,6 +223,7 @@ class Page_SystemStatus extends Page
protected function ajaxSysPoll()
{
+ User::assertPermission("show.overview.systeminfo");
$info = $this->sysInfo();
$data = array(
'CpuTotal' => $info['CpuTotal'],
@@ -228,10 +237,11 @@ class Page_SystemStatus extends Page
protected function ajaxServices()
{
+ User::assertPermission("show.overview.services");
$data = array('services' => array());
$tasks = array();
- $todo = ['dmsd', 'atftpd'];
+ $todo = ['dmsd', 'tftpd-hpa'];
if (Module::isAvailable('dnbd3') && Dnbd3::isEnabled()) {
$todo[] = 'dnbd3-server';
}
@@ -275,6 +285,7 @@ class Page_SystemStatus extends Page
protected function ajaxDmsdLog()
{
+ User::assertPermission("tab.dmsdlog");
$fh = @fopen('/var/log/dmsd.log', 'r');
if ($fh === false) {
echo 'Error opening log file';
@@ -307,6 +318,7 @@ class Page_SystemStatus extends Page
protected function ajaxLighttpdLog()
{
+ User::assertPermission("tab.lighttpdlog");
$fh = @fopen('/var/log/lighttpd/error.log', 'r');
if ($fh === false) {
echo 'Error opening log file';
@@ -339,6 +351,7 @@ class Page_SystemStatus extends Page
protected function ajaxLdadpLog()
{
+ User::assertPermission("tab.ldadplog");
$haveSysconfig = Module::isAvailable('sysconfig');
$files = glob('/var/log/ldadp/*.log', GLOB_NOSORT);
if ($files === false || empty($files)) echo('No logs found');
@@ -377,6 +390,7 @@ class Page_SystemStatus extends Page
protected function ajaxNetstat()
{
+ User::assertPermission("tab.netstat");
$taskId = Taskmanager::submit('Netstat');
if ($taskId === false)
return;
@@ -392,6 +406,7 @@ class Page_SystemStatus extends Page
protected function ajaxPsList()
{
+ User::assertPermission("tab.pslist");
$taskId = Taskmanager::submit('PsList');
if ($taskId === false)
return;
diff --git a/modules-available/systemstatus/permissions/permissions.json b/modules-available/systemstatus/permissions/permissions.json
new file mode 100644
index 00000000..29e26b5e
--- /dev/null
+++ b/modules-available/systemstatus/permissions/permissions.json
@@ -0,0 +1,35 @@
+{
+ "serverreboot": {
+ "location-aware": false
+ },
+ "tab.dmsdlog": {
+ "location-aware": false
+ },
+ "tab.netstat": {
+ "location-aware": false
+ },
+ "tab.pslist": {
+ "location-aware": false
+ },
+ "tab.ldadplog": {
+ "location-aware": false
+ },
+ "tab.lighttpdlog": {
+ "location-aware": false
+ },
+ "show.overview.addresses": {
+ "location-aware": false
+ },
+ "show.overview.diskstat": {
+ "location-aware": false
+ },
+ "show.overview.dmsdusers": {
+ "location-aware": false
+ },
+ "show.overview.services": {
+ "location-aware": false
+ },
+ "show.overview.systeminfo": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/systemstatus/templates/_page.html b/modules-available/systemstatus/templates/_page.html
index 0de94cad..64830ea3 100644
--- a/modules-available/systemstatus/templates/_page.html
+++ b/modules-available/systemstatus/templates/_page.html
@@ -11,11 +11,20 @@
</a>
</li>
{{#tabs}}
+ {{^enabled}}
+ <li class="disabled">
+ <a>
+ {{name}}
+ </a>
+ </li>
+ {{/enabled}}
+ {{#enabled}}
<li>
<a href="#id-{{type}}_pane" class="ajax-tab" id="id-{{type}}" data-toggle="tab" role="tab">
{{name}}
</a>
</li>
+ {{/enabled}}
{{/tabs}}
</ul>
@@ -83,10 +92,10 @@
{{lang_maintenance}}
</div>
<div class="panel-body">
- <form class="form-adduser" action="?do=SystemStatus" method="post">
+ <form action="?do=SystemStatus" method="post">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="reboot">
- <button class="btn btn-warning" type="button" data-toggle="modal" data-target="#rebootServerModal"><span class="glyphicon glyphicon-repeat"></span> {{lang_serverReboot}}</button>
+ <button {{perms.serverreboot.disabled}} class="btn btn-warning" type="button" data-toggle="modal" data-target="#rebootServerModal"><span class="glyphicon glyphicon-repeat"></span> {{lang_serverReboot}}</button>
<div class ="modal fade" id="rebootServerModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
diff --git a/modules-available/translation/config.json b/modules-available/translation/config.json
index 706412d0..110f8b67 100644
--- a/modules-available/translation/config.json
+++ b/modules-available/translation/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.content"
-}
+ "category": "main.content"
+} \ No newline at end of file
diff --git a/modules-available/translation/page.inc.php b/modules-available/translation/page.inc.php
index a5cdebed..7d5229d7 100644
--- a/modules-available/translation/page.inc.php
+++ b/modules-available/translation/page.inc.php
@@ -53,11 +53,30 @@ class Page_Translation extends Page
private function loadCustomHandler($moduleName)
{
$path = 'modules/' . $moduleName . '/hooks/translation.inc.php';
- if (!file_exists($path))
- return false;
$HANDLER = array();
- require $path;
- return $HANDLER;
+ if (file_exists($path)) {
+ require $path;
+ }
+ $backup = $HANDLER;
+ foreach (glob('modules/*/hooks/translation-global.inc.php', GLOB_NOSORT) as $path) {
+ $HANDLER = array();
+ require $path;
+ if (empty($HANDLER['subsections']))
+ continue;
+ foreach ($HANDLER['subsections'] as $sub) {
+ $suf = '';
+ while (isset($backup['subsections']) && in_array($sub . $suf, $backup['subsections'])) {
+ $suf = mt_rand();
+ }
+ $backup['subsections'][] = $sub . $suf;
+ if (isset($HANDLER['grep_' . $sub])) {
+ $backup['grep_' . $sub . $suf] = $HANDLER['grep_' . $sub];
+ }
+ }
+ }
+ if (empty($backup))
+ return false;
+ return $backup;
}
/**
@@ -81,7 +100,7 @@ class Page_Translation extends Page
{
User::load();
- if (!User::hasPermission('superadmin')) {
+ if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
@@ -445,19 +464,21 @@ class Page_Translation extends Page
$allFiles = array_merge($allFiles, $this->getAllFiles('apis', '.php'), $this->getAllFiles('inc', '.php'));
$allFiles[] = 'index.php';
}
- $tags = $this->loadTagsFromPhp('/Message\s*::\s*add\w+\s*\(\s*[\'"](?<module>[^\'"\.]*)\.(?<tag>[^\'"]*)[\'"]\s*(?<data>\)|\,.*)/i',
+ $full = $this->loadTagsFromPhp('/Message\s*::\s*add\w+\s*\(\s*[\'"](?<tag>[^\'"\.]*\.[^\'"]*)[\'"]\s*(?<data>\)|\,.*)/i',
$allFiles);
+ $tags = [];
// Filter out tags that don't refer to this module
- foreach (array_keys($tags) as $tag) {
+ foreach ($full as $tag) {
+ $p = explode('.', $tag['tag'], 2);
// Figure out if this is a message from this module or not
- if ($tags[$tag]['module'] === $module->getIdentifier()) {
+ if ($p[0] === $module->getIdentifier()) {
// Direct reference to this module via module.id
- continue;
+ $tag['tag'] = $p[1];
+ $tags[$p[1]] = $tag;
}
- unset($tags[$tag]);
}
- $tags += $this->loadTagsFromPhp('/Message\s*::\s*add\w+\s*\(\s*[\'"](?<tag>[^\'"\.]*)[\'"]\s*(?<data>\)|\,.*)/i',
- $this->getModulePhpFiles($module));
+ $tags = $this->loadTagsFromPhp('/Message\s*::\s*add\w+\s*\(\s*[\'"](?<tag>[^\'"\.]*)[\'"]\s*(?<data>\)|\,.*)/i',
+ $this->getModulePhpFiles($module), $tags);
return $tags;
}
@@ -812,12 +833,12 @@ class Page_Translation extends Page
*
* @param string $regexp regular expression
* @param array $files list of files to scan
+ * @param array $tags existing tag array to append to
* @return array of all tags found, where the tag is the key, and the value is as described above
*/
- private function loadTagsFromPhp($regexp, $files)
+ private function loadTagsFromPhp($regexp, $files, $tags = [])
{
// Get all php files, so we can find all strings that need to be translated
- $tags = array();
// Now find all tags in all php files. Only works for literal usage, not something like $foo = 'bar'; Dictionary::translate($foo);
foreach ($files as $file) {
$content = file_get_contents($file);
@@ -978,24 +999,20 @@ class Page_Translation extends Page
$data = array();
//find the tag requests to change the file
- foreach ($_POST as $key => $value) {
- $str = explode('#!#', $key, 2);
- if (count($str) !== 2)
+ $tags = Request::post('langtag', array(), 'array');
+ foreach ($tags as $tag => $value) {
+ error_log($tag . '=' . $value);
+ $tag = trim($tag);
+ if (empty($tag)) {
+ Message::addWarning('i18n-empty-tag');
continue;
- if ($str[0] === 'lang') {
- $tag = trim($str[1]);
- if (empty($tag)) {
- Message::addWarning('i18n-empty-tag');
- continue;
- }
- if (empty($value)) {
- unset($data[$tag]);
- } else {
- $data[$tag] = $value;
- }
+ }
+ if (empty($value)) {
+ unset($data[$tag]);
+ } else {
+ $data[$tag] = $value;
}
}
-
$translation = Request::post('new-text', array(), 'array');
foreach (Request::post('new-id', array(), 'array') as $k => $tag) {
if (empty($translation[$k]) || empty($tag))
diff --git a/modules-available/translation/templates/edit.html b/modules-available/translation/templates/edit.html
index 7a41d9b4..5b957067 100644
--- a/modules-available/translation/templates/edit.html
+++ b/modules-available/translation/templates/edit.html
@@ -35,10 +35,10 @@
<td class="col-sm-4" id="tagid-{{tagid}}">
{{^big}}
- <input type="text" class="form-control switchable {{#missing}}txt-empty{{/missing}}" value="{{translation}}" ondblclick="slxMb(this)" name="lang#!#{{tag}}" placeholder="{{placeholder}}">
+ <input type="text" class="form-control switchable {{#missing}}txt-empty{{/missing}}" value="{{translation}}" ondblclick="slxMb(this)" name="langtag[{{tag}}]" placeholder="{{placeholder}}">
{{/big}}
{{#big}}
- <textarea rows="3" class="form-control {{#missing}}txt-empty{{/missing}}" name="lang#!#{{tag}}" placeholder="{{placeholder}}">{{translation}}</textarea>
+ <textarea rows="3" class="form-control {{#missing}}txt-empty{{/missing}}" name="langtag[{{tag}}]" placeholder="{{placeholder}}">{{translation}}</textarea>
{{/big}}
</td>
@@ -81,7 +81,7 @@
var slxNewTagCounter = 0;
function slxAddTag()
{
- $('#moduleTable tr:last').after(
+ $('#moduleTable').find('tr:last').after(
'<tr id="new-delete-' + slxNewTagCounter + '">' +
' <td class="col-sm-3">' +
' <input type="text" name="new-id[' + slxNewTagCounter + ']" class="form-control">' +
diff --git a/modules-available/usermanagement/config.json b/modules-available/usermanagement/config.json
index 9c66d6bf..428315ba 100644
--- a/modules-available/usermanagement/config.json
+++ b/modules-available/usermanagement/config.json
@@ -1,4 +1,4 @@
{
- "category":"main.users",
- "permission":"0"
-}
+ "category": "main.users",
+ "permission": "0"
+} \ No newline at end of file
diff --git a/modules-available/vmstore/baseconfig/getconfig.inc.php b/modules-available/vmstore/baseconfig/getconfig.inc.php
index 75f7279b..3bad16e1 100644
--- a/modules-available/vmstore/baseconfig/getconfig.inc.php
+++ b/modules-available/vmstore/baseconfig/getconfig.inc.php
@@ -9,11 +9,17 @@ if (is_array($vmstore) && isset($vmstore['storetype'])) {
break;
case 'nfs';
ConfigHolder::add("SLX_VM_NFS", $vmstore['nfsaddr']);
+ if (!empty($vmstore['nfsopts'])) {
+ ConfigHolder::add("SLX_VM_NFS_OPTS", $vmstore['nfsopts']);
+ }
break;
case 'cifs';
ConfigHolder::add("SLX_VM_NFS", $vmstore['cifsaddr']);
ConfigHolder::add("SLX_VM_NFS_USER", $vmstore['cifsuserro']);
ConfigHolder::add("SLX_VM_NFS_PASSWD", $vmstore['cifspasswdro']);
+ if (!empty($vmstore['cifsopts'])) {
+ ConfigHolder::add("SLX_VM_NFS_OPTS", $vmstore['cifsopts']);
+ }
break;
}
}
diff --git a/modules-available/vmstore/config.json b/modules-available/vmstore/config.json
index 7205d70a..36268c6a 100644
--- a/modules-available/vmstore/config.json
+++ b/modules-available/vmstore/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.settings-server"
-}
+ "category": "main.settings-server"
+} \ No newline at end of file
diff --git a/modules-available/vmstore/lang/de/permissions.json b/modules-available/vmstore/lang/de/permissions.json
index f3148ea8..1f8d18d7 100644
--- a/modules-available/vmstore/lang/de/permissions.json
+++ b/modules-available/vmstore/lang/de/permissions.json
@@ -1,5 +1,3 @@
{
- "choose.internal": "Internen Speicher auswählen.",
- "choose.nfs": "Einen NFS Netzwerkspeicher auswählen.",
- "choose.cifs": "Einen CIFS Netzwerkspeicher auswählen."
+ "edit": "Den verwendeten VM-Speicher konfigurieren."
} \ No newline at end of file
diff --git a/modules-available/vmstore/lang/de/template-tags.json b/modules-available/vmstore/lang/de/template-tags.json
index 0b56d84f..8b6661c2 100644
--- a/modules-available/vmstore/lang/de/template-tags.json
+++ b/modules-available/vmstore/lang/de/template-tags.json
@@ -4,12 +4,12 @@
"lang_cifsHelp3": "Wenn exklusiv DNBD3 verwendet wird, k\u00f6nnen Sie den passwortlosen\r\nGastzugriff deaktivieren und die Zeile \"Nur-Lese-Zugangsdaten\" leer\r\nlassen. Dies erh\u00f6ht die Sicherheit.",
"lang_configure": "Konfigurieren",
"lang_internal": "Intern",
- "lang_nfsHelp1": "Ben\u00f6tigt wird ein NFSv4\/3-Share, der f\u00fcr den Satelliten-Server schreibbar, und f\u00fcr die Arbeitsstationen lesbar ist. Beispielkonfiguration auf dem NFS-Server, wenn der Satelliten-Server die Adresse 1.2.3.4 hat:",
+ "lang_nfsHelp1": "Ben\u00f6tigt wird ein NFSv4\/3-Share, der f\u00fcr den Satellitenserver schreibbar, und f\u00fcr die Arbeitsstationen lesbar ist. Beispielkonfiguration auf dem NFS-Server, wenn der Satellitenserver die Adresse 1.2.3.4 hat:",
"lang_nfsHelp2": "Alternative Konfiguration mittels all_squash. In diesem Fall muss das Verzeichnis auf dem Server dem Benutzer mit der uid 1234 geh\u00f6ren:",
"lang_nfsHelp3": "Die erste Zeile erlaubt den Lese- und Schreibzugriff des\r\nSatellitenservers. Die zweite Zeile erteilt allen anderen Rechnern\r\nausschlie\u00dflich Lesezugriff. Sie k\u00f6nnen dies nat\u00fcrlich auch auf\r\nspezielle Subnetze oder IP-Bereiche beschr\u00e4nken.",
"lang_nfsHelp4": "Wenn exklusiv DNBD3 verwendet wird, kann die zweite Zeile ausgelassen\r\nwerden. Dies erh\u00f6ht die Sicherheit.",
"lang_noAdditionalInformation": "Keine weitere Konfiguration notwendig",
- "lang_path": "Pfad",
+ "lang_optionalMountOptions": "Zu verwendende Mount-Optionen (optional):",
"lang_readOnly": "Nur-Lese-Zugangsdaten",
"lang_readWrite": "Lese\/Schreib-Zugangsdaten",
"lang_vmLocation": "VM Speicherort",
@@ -19,4 +19,4 @@
"lang_vmLocationHelp2": "Im Produktivbetrieb bietet es sich an, hierf\u00fcr einen performanten\r\nNetzwerkspeicher zu benutzen. Dieser Netzwerkspeicher kann per NFS oder\r\nCIFS\/SMB eingebunden werden. In jedem Fall muss sichergestellt werden,\r\ndass der Satellitenserver zum Hinzuf\u00fcgen neuer Virtueller Maschinen\r\nSchreibzugriff auf diesen Netzwerkspeicher hat. Bei der Nutzung von\r\nNFSv3 kann dies IP-Basiert eingerichtet werden, f\u00fcr die Nutzung von\r\nCIFS\/SMB k\u00f6nnen Sie Zugangsdaten angeben, die zum Schreiben\r\nberechtigen.",
"lang_vmLocationHelp3": "Im Fall von NFS und CIFS ben\u00f6tigen die bwLehrpool-Clients\r\nausschlie\u00dflich Lesezugriff auf den Netzwerkspeicher (und sollten aus\r\nSicherheitsgr\u00fcnden auch wirklich nur lesen k\u00f6nnen). Wenn Sie exklusiv\r\nDNBD3 verwenden, sind f\u00fcr die Clients keine Freigaben oder\r\nBerechtigungen notwendig, da der Zugriff \u00fcber den Sallitenserver\r\nstattfindet.",
"lang_vmLocationHelp4": "Sie k\u00f6nnen DNBD3 entweder exklusiv oder mit Fallback auf NFS\/CIFS verwenden. Im exklusiven Modus wird der Zugriff der Clients auf den kompletten VM-Speicher verhindert bzw. erschwert. Die Clients ben\u00f6tigen keinerlei Berechtigungen auf dem konfigurierten Share. Wenn Sie den Fallback Modus nutzen, werden f\u00fcr die Clients weiterhin Leseberechtigungen ben\u00f6tigt."
-}
+} \ No newline at end of file
diff --git a/modules-available/vmstore/lang/en/permissions.json b/modules-available/vmstore/lang/en/permissions.json
index 00708f7d..6d34014a 100644
--- a/modules-available/vmstore/lang/en/permissions.json
+++ b/modules-available/vmstore/lang/en/permissions.json
@@ -1,5 +1,3 @@
{
- "choose.internal": "Choose internal storage.",
- "choose.nfs": "Choose a NFS network storage.",
- "choose.cifs": "Choose a CIFS network storage."
+ "edit": "Configure VM storage to use."
} \ No newline at end of file
diff --git a/modules-available/vmstore/lang/en/template-tags.json b/modules-available/vmstore/lang/en/template-tags.json
index 1e712b13..5ec68318 100644
--- a/modules-available/vmstore/lang/en/template-tags.json
+++ b/modules-available/vmstore/lang/en/template-tags.json
@@ -9,7 +9,7 @@
"lang_nfsHelp3": "The first line allows read\/write access for the satellite server. The second line grants read-only access for every other IP address. You could limit the second line to specific IP ranges only if desired.",
"lang_nfsHelp4": "If using DNBD3 in exclusive mode, you can remove the second line completely, so only the satellite server has access to the NFS store.",
"lang_noAdditionalInformation": "No additional cofiguration required",
- "lang_path": "Path",
+ "lang_optionalMountOptions": "Mount options to use (optional):",
"lang_readOnly": "Read-only Access",
"lang_readWrite": "Read\/Write Access",
"lang_vmLocation": "VM Storage Location",
@@ -19,4 +19,4 @@
"lang_vmLocationHelp2": "In productive operation, it makes sense for this to use a high-performance network storage. This network storage can be integrated via NFS or CIFS \/ SMB. In any case, it must be ensured that the satellite server has write access to this network storage to add a new Virtual Machine . When using NFSv3 this can be set up IP-based, for the use of CIFS \/ SMB, you can access data disclosures that would entitle them to write.",
"lang_vmLocationHelp3": "The bwLehrpool clients only need read access to the network storage (and for security reasons, really can only read). In CIFS \/ SMB You can do this most easily by allowing passwordless guest access with read access to the share.",
"lang_vmLocationHelp4": "You can use DNBD3 exclusively or with NFS\/CIFS as fallback. In exclusive mode, you can deny direct access to the NFS\/CIFS store for clients, to prevent anyone from browsing the VM store directly. In fallback mode, the clients first try to use DNBD3 to run a VM and if that fails, they use NFS\/CIFS directly."
-}
+} \ No newline at end of file
diff --git a/modules-available/vmstore/page.inc.php b/modules-available/vmstore/page.inc.php
index c3d5da77..1e0cc619 100644
--- a/modules-available/vmstore/page.inc.php
+++ b/modules-available/vmstore/page.inc.php
@@ -8,10 +8,7 @@ class Page_VmStore extends Page
{
User::load();
- if (!User::isLoggedIn()) {
- Message::addError('main.no-permission');
- Util::redirect('?do=Main');
- }
+ User::assertPermission('edit');
$action = Request::post('action');
@@ -33,30 +30,25 @@ class Page_VmStore extends Page
if (isset($vmstore['storetype'])) {
$vmstore['pre-' . $vmstore['storetype']] = 'checked';
}
- $vmstore['internalAllowed'] = User::hasPermission("choose.internal");
- $vmstore['nfsAllowed'] = User::hasPermission("choose.nfs");
- $vmstore['cifsAllowed'] = User::hasPermission("choose.cifs");
- $vmstore['saveAllowed'] = $vmstore['internalAllowed'] || $vmstore['nfsAllowed'] || $vmstore['cifsAllowed'];
Render::addTemplate('page-vmstore', $vmstore);
}
private function setStore()
{
$vmstore = array();
- foreach (array('storetype', 'nfsaddr', 'cifsaddr', 'cifsuser', 'cifspasswd', 'cifsuserro', 'cifspasswdro') as $key) {
+ foreach (array('storetype', 'nfsaddr', 'nfsopts', 'cifsaddr', 'cifsuser', 'cifspasswd', 'cifsuserro', 'cifspasswdro', 'cifsopts') as $key) {
$vmstore[$key] = trim(Request::post($key, '', 'string'));
+ // Remove rw setting
+ if ($key === 'cifsopts' || $key === 'nfsopts') {
+ $vmstore[$key] = preg_replace('/\s+,\s+/', ',', $vmstore[$key]);
+ $vmstore[$key] = preg_replace('/^rw,|,rw$/', '', str_replace(',rw,', ',', $vmstore[$key]));
+ }
}
$storetype = $vmstore['storetype'];
if (!in_array($storetype, array('internal', 'nfs', 'cifs'))) {
Message::addError('main.value-invalid', 'type', $storetype);
Util::redirect('?do=VmStore');
}
- if (($storetype === 'internal' && !User::hasPermission("choose.internal")) ||
- ($storetype === 'nfs' && !User::hasPermission("choose.nfs")) ||
- ($storetype === 'cifs' && !User::hasPermission("choose.cifs"))) {
- Message::addError('main.no-permission');
- Util::redirect('?do=VmStore');
- }
// Validate syntax of nfs/cifs
if ($storetype === 'nfs' && !preg_match('#^\S+:\S+$#is', $vmstore['nfsaddr'])) {
Message::addError('main.value-invalid', 'nfsaddr', $vmstore['nfsaddr']);
diff --git a/modules-available/vmstore/permissions/permissions.json b/modules-available/vmstore/permissions/permissions.json
index f2c22c72..8303fd02 100644
--- a/modules-available/vmstore/permissions/permissions.json
+++ b/modules-available/vmstore/permissions/permissions.json
@@ -1,5 +1,5 @@
-[
- "choose.internal",
- "choose.nfs",
- "choose.cifs"
-] \ No newline at end of file
+{
+ "edit": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/vmstore/templates/page-vmstore.html b/modules-available/vmstore/templates/page-vmstore.html
index fece8e24..0e1ad601 100644
--- a/modules-available/vmstore/templates/page-vmstore.html
+++ b/modules-available/vmstore/templates/page-vmstore.html
@@ -9,7 +9,7 @@
<p>{{lang_vmLocationChoose}} <a class="btn btn-default" data-toggle="modal" data-target="#help-store"><span class="glyphicon glyphicon-question-sign"></span></a></p>
- <div class="panel panel-default {{^internalAllowed}}disabledPanel{{/internalAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">
<div class="radio">
<input type="radio" name="storetype" value="internal" {{pre-internal}} id="id-internal">
@@ -21,7 +21,7 @@
</div>
</div>
- <div class="panel panel-default {{^nfsAllowed}}disabledPanel{{/nfsAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">
<div class="radio radio-inline">
<input type="radio" name="storetype" value="nfs" {{pre-nfs}} id="id-nfs">
@@ -32,12 +32,15 @@
<div class="panel-body">
<label for="nfsaddr">NFS-Export</label>
<input type="text" class="form-control" name="nfsaddr" value="{{nfsaddr}}" placeholder="1.2.3.4:/export/bwlp" id="nfsaddr">
+ <br>
+ <label for="nfsopts">{{lang_optionalMountOptions}}</label>
+ <input type="text" class="form-control" name="nfsopts" value="{{nfsopts}}" placeholder="vers=4.0,async,nolock" id="nfsopts">
</div>
</div>
- <div class="panel panel-default {{^cifsAllowed}}disabledPanel{{/cifsAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">
<div class="radio radio-inline">
<input type="radio" name="storetype" value="cifs" {{pre-cifs}} id="id-cifs">
@@ -46,9 +49,12 @@
<a class="btn btn-default btn-sm" data-toggle="modal" data-target="#help-cifs"><span class="glyphicon glyphicon-question-sign"></span></a>
</div>
<div class="panel-body">
- <label for="cifsaddr">UNC-{{lang_path}}</label>
+ <label for="cifsaddr">UNC-Pfad</label>
<input type="text" class="form-control" name="cifsaddr" value="{{cifsaddr}}" placeholder="\\samba.server.example.com\bwlp" id="cifsaddr">
<br>
+ <label for="cifsopts">{{lang_optionalMountOptions}}</label>
+ <input type="text" class="form-control" name="cifsopts" value="{{cifsopts}}" placeholder="vers=3.0,sec=ntlmssp,nobrl,nounix" id="cifsopts">
+ <br>
<label for="cifsuser">{{lang_readWrite}}</label>
<div class="input-group">
<span class="input-group-addon slx-ga">
@@ -75,7 +81,7 @@
</div>
</div>
<div class="text-right">
- <button class="btn btn-primary" type="submit" {{^saveAllowed}}disabled{{/saveAllowed}}><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
</form>
diff --git a/modules-available/webinterface/config.json b/modules-available/webinterface/config.json
index 7205d70a..36268c6a 100644
--- a/modules-available/webinterface/config.json
+++ b/modules-available/webinterface/config.json
@@ -1,3 +1,3 @@
{
- "category":"main.settings-server"
-}
+ "category": "main.settings-server"
+} \ No newline at end of file
diff --git a/modules-available/webinterface/lang/de/permissions.json b/modules-available/webinterface/lang/de/permissions.json
index ee96810a..213ebd8f 100644
--- a/modules-available/webinterface/lang/de/permissions.json
+++ b/modules-available/webinterface/lang/de/permissions.json
@@ -1,5 +1,6 @@
{
- "edit.https": "HTTPS Einstellungen bearbeiten.",
- "edit.password": "Ändern, ob Passwortfelder in der Web-Schnittstelle maskiert werden sollen.",
- "edit.design": "Seitentitel und Hintergrundfarbe des Logos bearbeiten."
+ "access-page": "Seite sehen.",
+ "edit.design": "Seitentitel und Hintergrundfarbe des Logos bearbeiten.",
+ "edit.https": "HTTPS Einstellungen bearbeiten.",
+ "edit.password": "\u00c4ndern, ob Passwortfelder in der Web-Schnittstelle maskiert werden sollen."
} \ No newline at end of file
diff --git a/modules-available/webinterface/lang/en/permissions.json b/modules-available/webinterface/lang/en/permissions.json
index caf6d0cb..8ebb2830 100644
--- a/modules-available/webinterface/lang/en/permissions.json
+++ b/modules-available/webinterface/lang/en/permissions.json
@@ -1,5 +1,6 @@
{
- "edit.https": "Edit HTTPS settings.",
- "edit.password": "Change whether password fields should be masked or not.",
- "edit.design": "Edit page title and logo background color."
+ "access-page": "View page.",
+ "edit.design": "Edit page title and logo background color.",
+ "edit.https": "Edit HTTPS settings.",
+ "edit.password": "Change whether password fields should be masked or not."
} \ No newline at end of file
diff --git a/modules-available/webinterface/page.inc.php b/modules-available/webinterface/page.inc.php
index 41636c19..ca52c2ab 100644
--- a/modules-available/webinterface/page.inc.php
+++ b/modules-available/webinterface/page.inc.php
@@ -16,15 +16,22 @@ class Page_WebInterface extends Page
}
switch (Request::post('action')) {
case 'https':
- if (User::hasPermission("edit.https")) $this->actionConfigureHttps();
+ User::assertPermission("edit.https");
+ $this->actionConfigureHttps();
break;
case 'password':
- if (User::hasPermission("edit.password")) $this->actionShowHidePassword();
+ User::assertPermission("edit.password");
+ $this->actionShowHidePassword();
break;
case 'customization':
- if (User::hasPermission("edit.design")) $this->actionCustomization();
+ User::assertPermission("edit.design");
+ $this->actionCustomization();
break;
}
+ if (Request::isPost()) {
+ Util::redirect('?do=webinterface');
+ }
+ User::assertPermission('access-page');
}
private function actionConfigureHttps()
@@ -123,7 +130,7 @@ class Page_WebInterface extends Page
}
}
$data[$type . 'Selected'] = true;
- $data["editAllowed"] = User::hasPermission("edit.https");
+ Permission::addGlobalTags($data['perms'], null, ['edit.https']);
Render::addTemplate('https', $data);
//
// Password fields
@@ -133,8 +140,11 @@ class Page_WebInterface extends Page
$data['selected_show'] = 'checked';
else
$data['selected_hide'] = 'checked';
- $data["editAllowed"] = User::hasPermission("edit.password");
+ Permission::addGlobalTags($data['perms'], null, ['edit.password']);
Render::addTemplate('passwords', $data);
+ //
+ // Colors/Prefix
+ //
$data = array('prefix' => Property::get('page-title-prefix'));
$data['colors'] = array_map(function ($i) { return array('color' => $i ? '#' . $i : '', 'text' => Render::readableColor($i)); },
array('', 'f00', '0f0', '00f', 'ff0', 'f0f', '0ff', 'fff', '000', 'f90', '09f', '90f', 'f09', '9f0'));
@@ -150,7 +160,7 @@ class Page_WebInterface extends Page
if ($color) {
$data['colors'][] = array('color' => $color, 'selected' => 'selected');
}
- $data["editAllowed"] = User::hasPermission("edit.design");
+ Permission::addGlobalTags($data['perms'], null, ['edit.design']);
Render::addTemplate('customization', $data);
}
diff --git a/modules-available/webinterface/permissions/permissions.json b/modules-available/webinterface/permissions/permissions.json
index 45b5395d..ed81602a 100644
--- a/modules-available/webinterface/permissions/permissions.json
+++ b/modules-available/webinterface/permissions/permissions.json
@@ -1,5 +1,14 @@
-[
- "edit.https",
- "edit.password",
- "edit.design"
-] \ No newline at end of file
+{
+ "access-page": {
+ "location-aware": false
+ },
+ "edit.design": {
+ "location-aware": false
+ },
+ "edit.https": {
+ "location-aware": false
+ },
+ "edit.password": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/webinterface/style.css b/modules-available/webinterface/style.css
deleted file mode 100644
index 7b86af56..00000000
--- a/modules-available/webinterface/style.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.disabledPanel {
- cursor: not-allowed;
-}
-.disabledPanel > .panel-body {
- pointer-events: none;
- opacity: 0.8;
-}
diff --git a/modules-available/webinterface/templates/customization.html b/modules-available/webinterface/templates/customization.html
index ad57eea7..ea59d562 100644
--- a/modules-available/webinterface/templates/customization.html
+++ b/modules-available/webinterface/templates/customization.html
@@ -1,21 +1,21 @@
<form action="?do=WebInterface" method="post">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="customization">
- <div class="panel panel-default {{^editAllowed}}disabledPanel{{/editAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">{{lang_customization}}</div>
<div class="panel-body">
<p>{{lang_customizationDesc}}</p>
<div>
<label>
{{lang_pageTitlePrefix}}
- <input type="text" class="form-control" name="prefix" value="{{prefix}}">
+ <input type="text" class="form-control" name="prefix" value="{{prefix}}" {{perms.edit.design.disabled}}>
</label>
</div>
<div>
<label>
{{lang_logoBackground}}
- <select class="form-control" name="bgcolor">
+ <select class="form-control" name="bgcolor" {{perms.edit.design.disabled}}>
{{#colors}}
<option style="color:{{text}};background:{{color}}" {{selected}}>{{color}}</option>
{{/colors}}
@@ -23,7 +23,10 @@
</label>
</div>
<div class="pull-right">
- <button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button type="submit" class="btn btn-primary" {{perms.edit.design.disabled}}>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
</div>
</div>
</div>
diff --git a/modules-available/webinterface/templates/heading.html b/modules-available/webinterface/templates/heading.html
index d68360f1..59a8cf6b 100644
--- a/modules-available/webinterface/templates/heading.html
+++ b/modules-available/webinterface/templates/heading.html
@@ -1 +1,19 @@
-<h1>{{lang_moduleHeading}}</h1> \ No newline at end of file
+<div class="page-header">
+ <h1>{{lang_moduleHeading}}</h1>
+</div>
+<script><!--
+document.addEventListener('DOMContentLoaded', function () {
+ var $boxCustom = $('#wcustom');
+ $('.row-select').click(function (e) {
+ if (e.target.tagName === 'INPUT')
+ return;
+ $(e.target).closest('.row-select').find('input').click();
+ });
+ $('#cert-options').find('input').change(function(e) {
+ $boxCustom.toggle(e.target.id === 'mcustom');
+ });
+ if ($('#mcustom').is(':checked')) {
+ $boxCustom.show();
+ }
+});
+//--></script> \ No newline at end of file
diff --git a/modules-available/webinterface/templates/https.html b/modules-available/webinterface/templates/https.html
index a212cce3..ad36e9e5 100644
--- a/modules-available/webinterface/templates/https.html
+++ b/modules-available/webinterface/templates/https.html
@@ -1,7 +1,7 @@
<form action="?do=WebInterface" method="post">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="https">
- <div class="panel panel-default {{^editAllowed}}disabledPanel{{/editAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">{{lang_httpsSettings}}</div>
<div class="panel-body">
<p>{{lang_httpsDescription}}</p>
@@ -25,46 +25,45 @@
<p>{{lang_suppliedSelected}}</p>
{{/suppliedSelected}}
</div>
- {{#httpsEnabled}}
- <div class="input-group" onclick="$('#moff').prop('checked', true);
- $('#wcustom').hide()">
- <span class="input-group-addon">
- <div class="radio">
- <input id="moff" type="radio" name="mode" value="off">
- <label></label>
- </div>
- </span>
- <span class="form-control">
- {{lang_noHttps}}
- </span>
- </div>
- {{/httpsEnabled}}
- <div class="input-group" onclick="$('#mrandom').prop('checked', true);
- $('#wcustom').hide()">
- <span class="input-group-addon">
- <div class="radio">
- <input id="mrandom" type="radio" name="mode" value="random">
- <label></label>
- </div>
- </span>
- <span class="form-control">
- {{lang_randomCert}}
- </span>
- </div>
- <div class="input-group" onclick="$('#mcustom').prop('checked', true);
- $('#wcustom').show()">
- <span class="input-group-addon">
- <div class="radio">
- <input id="mcustom" type="radio" name="mode" value="custom">
- <label></label>
- </div>
- </span>
- <span class="form-control">
- {{lang_customCert}}
- </span>
+ <div id="cert-options">
+ {{#httpsEnabled}}
+ <div class="input-group row-select">
+ <span class="input-group-addon">
+ <span class="radio">
+ <input id="moff" type="radio" name="mode" value="off" {{perms.edit.https.disabled}}>
+ <label></label>
+ </span>
+ </span>
+ <span class="form-control">
+ {{lang_noHttps}}
+ </span>
+ </div>
+ {{/httpsEnabled}}
+ <div class="input-group row-select">
+ <span class="input-group-addon">
+ <span class="radio">
+ <input id="mrandom" type="radio" name="mode" value="random" {{perms.edit.https.disabled}}>
+ <label></label>
+ </span>
+ </span>
+ <span class="form-control">
+ {{lang_randomCert}}
+ </span>
+ </div>
+ <div class="input-group row-select">
+ <span class="input-group-addon">
+ <span class="radio">
+ <input id="mcustom" type="radio" name="mode" value="custom" {{perms.edit.https.disabled}}>
+ <label></label>
+ </span>
+ </span>
+ <span class="form-control">
+ {{lang_customCert}}
+ </span>
+ </div>
</div>
- <div class="well well-sm" style="display:none" id="wcustom">
+ <div class="well well-sm collapse" id="wcustom">
{{lang_certificate}}
<pre class="small">
-----BEGIN CERTIFICATE-----
@@ -87,32 +86,35 @@ MIIFfTCCA...
</div>
<br>
- <div class="input-group">
+ <div class="input-group row-select">
<span class="input-group-addon">
- <div class="checkbox">
- <input id="httpsredirect" type="checkbox" name="httpsredirect" value="on" {{redirect_checked}}>
+ <span class="checkbox">
+ <input id="httpsredirect" type="checkbox" name="httpsredirect" value="on" {{redirect_checked}} {{perms.edit.https.disabled}}>
<label></label>
- </div>
+ </span>
</span>
- <span class="form-control" onclick="$('#httpsredirect').prop('checked', !$('#httpsredirect').prop('checked'))">
+ <span class="form-control">
{{lang_httpsRedirect}}
</span>
</div>
- <div class="input-group">
+ <div class="input-group row-select">
<span class="input-group-addon">
- <div class="checkbox">
- <input id="usehsts" type="checkbox" name="usehsts" value="on" {{hsts_checked}}>
+ <span class="checkbox">
+ <input id="usehsts" type="checkbox" name="usehsts" value="on" {{hsts_checked}} {{perms.edit.https.disabled}}>
<label></label>
- </div>
+ </span>
</span>
- <span class="form-control" onclick="$('#usehsts').prop('checked', !$('#usehsts').prop('checked'))">
+ <span class="form-control">
{{lang_useHsts}}
</span>
</div>
<br>
<div class="pull-right">
- <button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button type="submit" class="btn btn-primary" {{perms.edit.https.disabled}}>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
</div>
</div>
</div>
diff --git a/modules-available/webinterface/templates/passwords.html b/modules-available/webinterface/templates/passwords.html
index 1d73c172..b61c8ce9 100644
--- a/modules-available/webinterface/templates/passwords.html
+++ b/modules-available/webinterface/templates/passwords.html
@@ -1,27 +1,27 @@
<form action="?do=WebInterface" method="post">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="password">
- <div class="panel panel-default {{^editAllowed}}disabledPanel{{/editAllowed}}">
+ <div class="panel panel-default">
<div class="panel-heading">{{lang_passwordFields}}</div>
<div class="panel-body">
<p>{{lang_passwordsDescription}}</p>
- <div class="input-group" onclick="$('#pmshow').prop('checked', true)">
+ <div class="input-group row-select">
<span class="input-group-addon">
- <div class="radio">
- <input id="pmshow" type="radio" name="mode" value="show" {{selected_show}}>
+ <span class="radio">
+ <input id="pmshow" type="radio" name="mode" value="show" {{selected_show}} {{perms.edit.password.disabled}}>
<label></label>
- </div>
+ </span>
</span>
<span class="form-control">
{{lang_showPasswords}}
</span>
</div>
- <div class="input-group" onclick="$('#pmhide').prop('checked', true)">
+ <div class="input-group row-select">
<span class="input-group-addon">
- <div class="radio">
- <input id="pmhide" type="radio" name="mode" value="hide" {{selected_hide}}>
+ <span class="radio">
+ <input id="pmhide" type="radio" name="mode" value="hide" {{selected_hide}} {{perms.edit.password.disabled}}>
<label></label>
- </div>
+ </span>
</span>
<span class="form-control">
{{lang_hidePasswords}}
@@ -29,7 +29,10 @@
</div>
<br>
<div class="pull-right">
- <button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button type="submit" class="btn btn-primary" {{perms.edit.password.disabled}}>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
</div>
</div>
</div>