TODO
=====

- Email recurrence related properties for recurring meeting requests.

- SCHEMA support in ITEMOPERATIONS requests. Don't have client that supports
  currently.

- Implement some sort of issue tracking/counting to prevent loops due to things
  like clients not supporting standard status codes, like FOLDERSYNC_REQUIRED.
  Send the error code up to a maximum number of times, and after that send a
  server 500-ish error code indicating the client should stop trying. Probably
  store data in device object, but need to figure out how to prevent race
  conditions since multiple requests can be in progress. Perhaps some sort
  of shared memory cache?

- Perhaps if we use a shared memory solution, we can also possibly create
  some sort of top-like application to monitor EAS usage. Make it easier to
  find troublesome devices etc....

- Work out / more fully test Task recurrence. Especially completion of a single
  instance using DEADRECUR etc... (most work is in Nag, but put here to keep
  sync todos together).

- Add support for throttling via HTTP 503 and the X-MS-Throttle header.
  (See https://docs.microsoft.com/en-us/previous-versions/office/developer/exchange-server-interoperability-guidance/jj899829(v%3dexchg.140))

BC BREAKING (i.e., Horde 6).
============================

- Move all non-specific constants to single class.

- Clean up the various foldertype constant messes. I.e., probably store
  the Horde_ActiveSync::FOLDER_TYPE_* and Horde_ActiveSync::CLASS_* values
  in the saved state instead of having to switch between them in various
  places. (Some client commands are sent using the CLASS, some using the
  FOLDER_TYPE).

- Clean up and refactor the folder creation/editing/deleting methods in the
  backend. They need to be normalized in accepting/returning the same objects
  now that we support multiple folders per non-email collection.

- Refactor Horde_ActiveSync_State_*::listDevices() to return a
  Horde_ActiveSync_Device object instead of a hash keyed by backend field names
  and to take the object property names as filters instead of backend field names.

- Clean up logger creation/setting/log_level setting and provide a single
  access point for the logger instead of injecting it everywhere. Possibly
  implement Horde_ActiveSync_Debug to handle all logging duties.

- Refactor out the need for the various static ::_* properties in the main
  ActiveSync class.

- Change the readable names of the WBXML tags to reflect what they are called
  in the MS-AS* documents, and not what Z-Push's developers decided to call them.

- Look at extracting something like Request_Parser and Request_Handler classes
  to separate the reading of the request from the handling of it. The parser
  should return some standard request object that can be passed to the handler
  that contains the pertinent information. Use temporary streams to hold any
  incoming message data to preserve the low memory footprint from dealing with
  changes as we read them.

- Consolidate folderUid <-> backend id mapping methods into a single place.
  Currently they live in both the collection handler and the backend driver.

- Maintain the serverid -> backendid map in a single place and stop storing
  backend ids (i.e., IMAP folder names) in collection/state/folder cache etc...
  Also, standardize on using the serverid value everwhere within H_AS code.
  backendid should be just that - only used when communicating with the backend.

- Possibly move the syncCache and state into the device object so we have a
  single object to pass around that has access to all.

- Extract a basic Horde_ActiveSync_Storage class? At the very least we need to
  rename the current Horde_ActiveSync_State_* classes to Horde_ActiveSync_Storage
  since they now deal with more than device state.

- Implmement Horde_ActiveSync_HttpRequest object and remove dependency on
  Horde_Controller. We only use the Horde_Controller_Request_Http object from
  that package.

- Implmement A Horde_ActiveSync_Response object and move functionality currently
  living in the RPC layer (sending back certain headers, etc...) into this
  class.

- Implement a Horde_ActiveSync_Change_Filter class/interface. Used to implement
  workarounds for broken clients. E.g., filter out the ADD commands sent in
  response to MOVEITEMS for Outlook clients. Use a similar pattern for other
  types of broken client behavior.

- No longer ignore SMS synchronization in the library, but pass it up to the
  backend and the let the backend decide what to do with it. Since the SMS
  ability of EAS uses the device to actually send the SMS, I could foresee
  some added ability in IMP, or maybe a separate app, that allows managing this.

- Break up Horde_ActiveSync_Driver::getMessage(). Add _getCalendarMessage() etc...
  and move base logic for calling the correct method into the base class.

- Decouple the codepage definitions from the Encoder/Decoder class. Break them
  out into individual classes.

- Pass the Horde_ActiveSync::FILTERTYPE_ constant directly to the driver, and
  let the driver calculate the needed time slice if needed. Needed to correctly
  deal with Horde_ActiveSync::FILTERTYPE_INCOMPLETETASKS.

- Introduce some sort of filter or similar data in the definitions of the wbxml
  fields to allow for things like specifying the maximum size of a field allowed.

- Move Horde_Core_ActiveSync_Mail into the Horde_ActiveSync library.
  Horde_ActiveSync_Mailer (?). This is functionality that should be provided
  out of the box from the library. Need to figure out the best way to inject the
  Horde specific things, like the actual mailer and identity data.

- Implement something like Horde_ActiveSync_Sync_Options:: to encapsulate loading
  and transporting the various collection options/bodyprefs around.

- Likewise, implement a collection object instead of using an array to define
  each collection and have it be responsible for providing some of the return
  objects/values (See comments in Sync.php).

- Implement Horde_ActiveSync_SyncKey.

- Move non server-ish methods out of Horde_ActiveSync(_Server). E.g.,
  getMimeTrucSize() etc...

- Implment a "changes" object that uses either an array/spl array, or a
  temporary php stream (for the larger initial email syncs) to store the actual
  change data structure. Needed to avoid hitting PHP memory limit for very large
  mailboxes when synchronizing to clients that pull the entire mailbox down
  (like Outlook). Also, standardize the data format instead of having to
  (re)build a flat array from a multidimensional array of 'changes', 'add' etc..

- Use a configuration object (or maybe a Builder) for constructing the
  ActiveSync Driver and Server objects. At the very least, need to clean up the
  constructor parameters and various configuration options mess. (E.g., the
  "PING" configuration values are no longer really all strictly related to PING
  requests).

- Implement a Repository pattern for adding/supporting each backend collection
  type instead of using a monolithic driver/connector object.

- Use a Horde_ActiveSync_Date or Horde_ActiveSync_Message_Date object to wrap
  logic such as NormalizePoomContactsDate etc...

- Clean up exception types, add Horde_ActiveSync_Protocol_Exception etc...

- Implement some type of SYNC_REPLY object that is responsible for outputing
  the SYNC_REPLY data for itself. E.g., return such an object from the
  H_A_S_Driver::changeMessage either instead of a $stat array, or as part
  of the $stat array. Move functionality in H_A_S_Exporter_Sync::syncAddResponse
  and ::syncModifiedResponse() into these new objects. Probably need concrete
  classes for Calendar and Email etc...

- Clean up Horde_ActiveSync_Device - break into device specific child classes.
