text:
//
//  Localytics.h
//  Copyright (C) 2014 Char Software Inc., DBA Localytics
//
//  This code is provided under the Localytics Modified BSD License.
//  A copy of this license has been distributed in a file called LICENSE
//  with this source code.
//
// Please visit www.localytics.com for more information.
//

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

#define LOCALYTICS_LIBRARY_VERSION      @"3.8.0"

typedef NS_ENUM(NSUInteger, LLInAppMessageDismissButtonLocation){
    LLInAppMessageDismissButtonLocationLeft,
    LLInAppMessageDismissButtonLocationRight
};

typedef NS_ENUM(NSInteger, LLProfileScope){
    LLProfileScopeApplication,
    LLProfileScopeOrganization
};

@protocol LLMessagingDelegate;
@protocol LLAnalyticsDelegate;

@class LLInboxCampaign;
@class LLInboxDetailViewController;

/**
 @discussion The class which manages creating, collecting, & uploading a Localytics session.
 Please see the following guides for information on how to best use this
 library, sample code, and other useful information:

 Main Developer's Integration Guide

 Best Practices

Integrate Localytics in applicationDidFinishLaunching.

Open your session and begin your uploads in applicationDidBecomeActive. This way the
 upload has time to complete and it all happens before your users have a
 chance to begin any data intensive actions of their own.

Close the session in applicationWillResignActive.

Do not call any Localytics functions inside a loop.  Instead, calls
 such as tagEvent should follow user actions.  This limits the
 amount of data which is stored and uploaded.

Do not instantiate a Localtyics object, instead use only the exposed class methods.

 */

@interface Localytics : NSObject

#pragma mark - SDK Integration
/** ---------------------------------------------------------------------------------------
 * @name Localytics SDK Integration
 *  ---------------------------------------------------------------------------------------
 */

/** Auto-integrates the Localytic SDK into the application.

 Use this method to automatically integrate the Localytics SDK in a single line of code. Automatic
 integration is accomplished by proxing the AppDelegate and "inserting" a Localytics AppDelegate
 behind the applications AppDelegate. The proxy will first call the applications AppDelegate and
 then call the Localytics AppDelegate.

 @param appKey The unique key for each application generated at www.localytics.com
 @param launchOptions The launchOptions provided by application:DidFinishLaunchingWithOptions:
 */
+ (void)autoIntegrate:(NSString *)appKey launchOptions:(NSDictionary *)launchOptions;

/** Manually integrate the Localytic SDK into the application.

 Use this method to manually integrate the Localytics SDK. The developer still has to make sure to
 open and close the Localytics session as well as call upload to ensure data is uploaded to
 Localytics

 @param appKey The unique key for each application generated at www.localytics.com
 @see openSession
 @see closeSession
 @see upload
 */
+ (void)integrate:(NSString *)appKey;

/** Opens the Localytics session.
 The session time as presented on the website is the time between open and the
 final close so it is recommended to open the session as early as possible, and close
 it at the last moment. It is recommended that this call be placed in applicationDidBecomeActive.

 If for any reason this is called more than once every subsequent open call will be ignored.

 Resumes the Localytics session.  When the App enters the background, the session is
 closed and the time of closing is recorded.  When the app returns to the foreground, the session
 is resumed.  If the time since closing is greater than BACKGROUND_SESSION_TIMEOUT, (15 seconds
 by default) a new session is created, and uploading is triggered.  Otherwise, the previous session
 is reopened.
 */
+ (void)openSession;

/** Closes the Localytics session.  This should be called in
 applicationWillResignActive.

 If close is not called, the session will still be uploaded but no
 events will be processed and the session time will not appear. This is
 because the session is not yet closed so it should not be used in
 comparison with sessions which are closed.
 */
+ (void)closeSession;

/** Creates a low priority thread which uploads any Localytics data already stored
 on the device.  This should be done early in the process life in order to
 guarantee as much time as possible for slow connections to complete.  It is also reasonable
 to upload again when the application is exiting because if the upload is cancelled the data
 will just get uploaded the next time the app comes up.
 */
+ (void)upload;

#pragma mark - Event Tagging
/** ---------------------------------------------------------------------------------------
 * @name Event Tagging
 *  ---------------------------------------------------------------------------------------
 */

/** Tag an event
 @param eventName The name of the event which occurred.
 @see tagEvent:attributes:customerValueIncrease:
 */
+ (void)tagEvent:(NSString *)eventName;

/** Tag an event with attributes
 @param eventName The name of the event which occurred.
 @param attributes An object/hash/dictionary of key-value pairs, contains
 contextual data specific to the event.
 @see tagEvent:attributes:customerValueIncrease:
 */
+ (void)tagEvent:(NSString *)eventName attributes:(NSDictionary *)attributes;

/** Allows a session to tag a particular event as having occurred.  For
 example, if a view has three buttons, it might make sense to tag
 each button click with the name of the button which was clicked.
 For another example, in a game with many levels it might be valuable
 to create a new tag every time the user gets to a new level in order
 to determine how far the average user is progressing in the game.

 Tagging Best Practices

DO NOT use tags to record personally identifiable information.

The best way to use tags is to create all the tag strings as predefined
 constants and only use those.  This is more efficient and removes the risk of
 collecting personal information.

Do not set tags inside loops or any other place which gets called
 frequently.  This can cause a lot of data to be stored and uploaded.

 See the tagging guide at: http://wiki.localytics.com/
 @param eventName The name of the event which occurred.
 @param attributes (Optional) An object/hash/dictionary of key-value pairs, contains
 contextual data specific to the event.
 @param customerValueIncrease (Optional) Numeric value, added to customer lifetime value.
 Integer expected. Try to use lowest possible unit, such as cents for US currency.
 */
+ (void)tagEvent:(NSString *)eventName attributes:(NSDictionary *)attributes customerValueIncrease:(NSNumber *)customerValueIncrease;

#pragma mark - Tag Screen Method

/** Allows tagging the flow of screens encountered during the session.
 @param screenName The name of the screen
 */

+ (void)tagScreen:(NSString *)screenName;

#pragma mark - Custom Dimensions
/** ---------------------------------------------------------------------------------------
 * @name Custom Dimensions
 *  ---------------------------------------------------------------------------------------
 */

/** Sets the value of a custom dimension. Custom dimensions are dimensions
 which contain user defined data unlike the predefined dimensions such as carrier, model, and country.
 Once a value for a custom dimension is set, the device it was set on will continue to upload that value
 until the value is changed. To clear a value pass nil as the value.
 The proper use of custom dimensions involves defining a dimension with less than ten distinct possible
 values and assigning it to one of the four available custom dimensions. Once assigned this definition should
 never be changed without changing the App Key otherwise old installs of the application will pollute new data.
 @param value The value to set the custom dimension to
 @param dimension The dimension to set the value of
 @see valueForCustomDimension:
 */
+ (void)setValue:(NSString *)value forCustomDimension:(NSUInteger)dimension;

/** Gets the custom value for a given dimension. Avoid calling this on the main thread, as it
 may take some time for all pending database execution.
 @param dimension The custom dimension to return a value for
 @return The current value for the given custom dimension
 @see setValue:forCustomDimension:
 */
+ (NSString *)valueForCustomDimension:(NSUInteger)dimension;

#pragma mark - Identifiers
/** ---------------------------------------------------------------------------------------
 * @name Identifiers
 *  ---------------------------------------------------------------------------------------
 */

/** Sets the value of a custom identifier. Identifiers are a form of key/value storage
 which contain custom user data. Identifiers might include things like email addresses,
 customer IDs, twitter handles, and facebook IDs. Once a value is set, the device it was set
 on will continue to upload that value until the value is changed.
 To delete a property, pass in nil as the value.
 @param value The value to set the identifier to. To delete a propert set the value to nil
 @param identifier The name of the identifier to have it's value set
 @see valueForIdentifier:
 */
+ (void)setValue:(NSString *)value forIdentifier:(NSString *)identifier;

/** Gets the identifier value for a given identifier. Avoid calling this on the main thread, as it
 may take some time for all pending database execution.
 @param identifier The identifier to return a value for
 @return The current value for the given identifier
 @see setValue:forCustomDimension:
 */
+ (NSString *)valueForIdentifier:(NSString *)identifier;

/** This is an identifier helper method. This method acts the same as calling
    [Localytics setValue:userId forIdentifier:@"customer_id"]
 @param customerId The user id to set the 'customer_id' identifier to
 */
+ (void)setCustomerId:(NSString *)customerId;

/** Gets the customer id. Avoid calling this on the main thread, as it
 may take some time for all pending database execution.
 @return The current value for customer id
 */
+ (NSString *)customerId;

/** Stores the user's location.  This will be used in all event and session calls.
 If your application has already collected the user's location, it may be passed to Localytics
 via this function.  This will cause all events and the session close to include the location
 information.  It is not required that you call this function.
 @param location The user's location.
 */
+ (void)setLocation:(CLLocationCoordinate2D)location;

#pragma mark - Profile
/** ---------------------------------------------------------------------------------------
 * @name Profile
 *  ---------------------------------------------------------------------------------------
 */

/** Sets the value of a profile attribute.
 @param value The value to set the profile attribute to. value can be one of the following: NSString,
 NSNumber(long & int), NSDate, NSArray of Strings, NSArray of NSNumbers(long & int), NSArray of Date,
 nil. Passing in a 'nil' value will result in that attribute being deleted from the profile
 @param attribute The name of the profile attribute to be set
 @param scope The scope of the attribute governs the visability of the profile attribute (application
 only or organization wide)
 */
+ (void)setValue:(NSObject *)value forProfileAttribute:(NSString *)attribute withScope:(LLProfileScope)scope;

/** Sets the value of a profile attribute (scope: Application).
 @param value The value to set the profile attribute to. value can be one of the following: NSString,
 NSNumber(long & int), NSDate, NSArray of Strings, NSArray of NSNumbers(long & int), NSArray of Date,
 nil. Passing in a 'nil' value will result in that attribute being deleted from the profile
 @param attribute The name of the profile attribute to be set
 */
+ (void)setValue:(NSObject *)value forProfileAttribute:(NSString *)attribute;

/** Adds values to a profile attribute that is a set
 @param values The value to be added to the profile attributes set
 @param attribute The name of the profile attribute to have it's set modified
 @param scope The scope of the attribute governs the visability of the profile attribute (application
 only or organization wide)
 */
+ (void)addValues:(NSArray *)values toSetForProfileAttribute:(NSString *)attribute withScope:(LLProfileScope)scope;

/** Adds values to a profile attribute that is a set (scope: Application).
 @param values The value to be added to the profile attributes set
 @param attribute The name of the profile attribute to have it's set modified
 */
+ (void)addValues:(NSArray *)values toSetForProfileAttribute:(NSString *)attribute;

/** Removes values from a profile attribute that is a set
 @param values The value to be removed from the profile attributes set
 @param attribute The name of the profile attribute to have it's set modified
 @param scope The scope of the attribute governs the visability of the profile attribute (application
 only or organization wide)
 */
+ (void)removeValues:(NSArray *)values fromSetForProfileAttribute:(NSString *)attribute withScope:(LLProfileScope)scope;

/** Removes values from a profile attribute that is a set (scope: Application).
 @param values The value to be removed from the profile attributes set
 @param attribute The name of the profile attribute to have it's set modified
 */
+ (void)removeValues:(NSArray *)values fromSetForProfileAttribute:(NSString *)attribute;

/** Increment the value of a profile attribute.
 @param value An NSInteger to be added to an existing profile attribute value.
 @param attribute The name of the profile attribute to have it's value incremented
 @param scope The scope of the attribute governs the visability of the profile attribute (application
 only or organization wide)
 */
+ (void)incrementValueBy:(NSInteger)value forProfileAttribute:(NSString *)attribute withScope:(LLProfileScope)scope;

/** Increment the value of a profile attribute (scope: Application).
 @param value An NSInteger to be added to an existing profile attribute value.
 @param attribute The name of the profile attribute to have it's value incremented
 */
+ (void)incrementValueBy:(NSInteger)value forProfileAttribute:(NSString *)attribute;

/** Decrement the value of a profile attribute.
 @param value An NSInteger to be subtracted from an existing profile attribute value.
 @param attribute The name of the profile attribute to have it's value decremented
 @param scope The scope of the attribute governs the visability of the profile attribute (application
 only or organization wide)
 */
+ (void)decrementValueBy:(NSInteger)value forProfileAttribute:(NSString *)attribute withScope:(LLProfileScope)scope;

/** Decrement the value of a profile attribute (scope: Application).
 @param value An NSInteger to be subtracted from an existing profile attribute value.
 @param attribute The name of the profile attribute to have it's value decremented
 */
+ (void)decrementValueBy:(NSInteger)value forProfileAttribute:(NSString *)attribute;

/** Delete a profile attribute
 @param attribute The name of the attribute to be deleted
 @param scope The scope of the attribute governs the visability of the profile attribute (application
 only or organization wide)
 */
+ (void)deleteProfileAttribute:(NSString *)attribute withScope:(LLProfileScope)scope;

/** Delete a profile attribute (scope: Application)
 @param attribute The name of the attribute to be deleted
 */
+ (void)deleteProfileAttribute:(NSString *)attribute;

/** Convenience method to set a customer's email as both a profile attribute and
 as a customer identifier (scope: Organization)
 @param email Customer's email
 */
+ (void)setCustomerEmail:(NSString *)email;

/** Convenience method to set a customer's first name as both a profile attribute and
 as a customer identifier (scope: Organization)
 @param firstName Customer's first name
 */
+ (void)setCustomerFirstName:(NSString *)firstName;

/** Convenience method to set a customer's last name as both a profile attribute and
 as a customer identifier (scope: Organization)
 @param lastName Customer's last name
 */
+ (void)setCustomerLastName:(NSString *)lastName;

/** Convenience method to set a customer's full name as both a profile attribute and
 as a customer identifier (scope: Organization)
 @param fullName Customer's full name
 */
+ (void)setCustomerFullName:(NSString *)fullName;

#pragma mark - Push
/** ---------------------------------------------------------------------------------------
 * @name Push
 *  ---------------------------------------------------------------------------------------
 */

/** Returns the device's APNS token if one has been set via setPushToken: previously.
 @return The device's APNS token if one has been set otherwise nil
 @see setPushToken:
 */
+ (NSString *)pushToken;

/** Stores the device's APNS token. This will be used in all event and session calls.
 @param pushToken The devices APNS token returned by application:didRegisterForRemoteNotificationsWithDeviceToken:
 @see pushToken
 */
+ (void)setPushToken:(NSData *)pushToken;

/** Used to record performance data for push notifications
 @param notificationInfo The dictionary from either didFinishLaunchingWithOptions or
 didReceiveRemoteNotification should be passed on to this method
 */
+ (void)handlePushNotificationOpened:(NSDictionary *)notificationInfo;

#pragma mark - In-App Message
/** ---------------------------------------------------------------------------------------
 * @name In-App Message
 *  ---------------------------------------------------------------------------------------
 */

/**
 @param url The URL to be handled
 @return YES if the URL was successfully handled or NO if the attempt to handle the
 URL failed.
 */
+ (BOOL)handleTestModeURL:(NSURL *)url;

/** Set the image to be used for dimissing an In-App message
 @param image The image to be used for dismissing an In-App message. By default this is a
 circle with an 'X' in the middle of it
 */
+ (void)setInAppMessageDismissButtonImage:(UIImage *)image;

/** Set the image to be used for dimissing an In-App message by providing the name of the
 image to be loaded and used
 @param imageName The name of an image to be loaded and used for dismissing an In-App
 message. By default the image is a circle with an 'X' in the middle of it
 */
+ (void)setInAppMessageDismissButtonImageWithName:(NSString *)imageName;

/** Set the location of the dismiss button on an In-App msg
 @param location The location of the button (left or right)
 @see InAppDismissButtonLocation
 */
+ (void)setInAppMessageDismissButtonLocation:(LLInAppMessageDismissButtonLocation)location;

/** Returns the location of the dismiss button on an In-App msg
 @return InAppDismissButtonLocation
 @see InAppDismissButtonLocation
 */
+ (LLInAppMessageDismissButtonLocation)inAppMessageDismissButtonLocation;

+ (void)triggerInAppMessage:(NSString *)triggerName;
+ (void)triggerInAppMessage:(NSString *)triggerName withAttributes:(NSDictionary *)attributes;

+ (void)dismissCurrentInAppMessage;

#pragma mark - Inbox

/** Returns an array of all Inbox campaigns that are enabled and ready for display.
 @return an array of LLInboxCampaign objects
 */
+ (NSArray<LLInboxCampaign *> *)inboxCampaigns;

/** Refresh inbox campaigns from the Localytics server.
 @param completionBlock the block invoked with refresh is complete
 */
+ (void)refreshInboxCampaigns:(void (^)(NSArray<LLInboxCampaign *> *inboxCampaigns))completionBlock;

/** Set an Inbox campaign as read. Read state can be used to display opened but not disabled Inbox
 campaigns differently (e.g. greyed out).
 @param campaignId the campaign ID of the Inbox campaign.
 @param read YES to mark the campaign as read, NO to mark it as unread
 @see [LLInboxCampaign class]
 */
+ (void)setInboxCampaignId:(NSInteger)campaignId asRead:(BOOL)read;

/** Returns a inbox campaign detail view controller with the given inbox campaign data.
 @return a LLInboxDetailViewController from a given LLInboxCampaign object
 */
+ (LLInboxDetailViewController *)inboxDetailViewControllerForCampaign:(LLInboxCampaign *)campaign;

#pragma mark - Developer Options
/** ---------------------------------------------------------------------------------------
 * @name Developer Options
 *  ---------------------------------------------------------------------------------------
 */

/** Returns whether the Localytics SDK is set to emit logging information
 @return YES if logging is enabled, NO otherwise
 */
+ (BOOL)isLoggingEnabled;

/** Set whether Localytics SDK should emit logging information. By default the Localytics SDK
 is set to not to emit logging information. It is recommended that you only enable logging
 for debugging purposes.
 @param loggingEnabled Set to YES to enable logging or NO to disable it
 */
+ (void)setLoggingEnabled:(BOOL)loggingEnabled;

/** Returns whether or not an IDFA is collected and sent to Localytics
 @return YES if an IDFA is collected, NO otherwise
 @see setCollectAdvertisingIdentifier
 */
+ (BOOL)isCollectingAdvertisingIdentifier;

/** Set whether or not an IDFA is collected and sent to Localytics
 @param collectAdvertisingIdentifier When set to YES an IDFA is collected. No prevents the IDFA
 from being collected. By default an IDFA is collected
 @see isCollectingAdvertisingIdentifier
 */
+ (void)setCollectAdvertisingIdentifier:(BOOL)collectAdvertisingIdentifier;

/** Returns whether or not the application will collect user data.
 @return YES if the user is opted out, NO otherwise. Default is NO
 @see setOptedOut:
 */
+ (BOOL)isOptedOut;

/** Allows the application to control whether or not it will collect user data.
 Even if this call is used, it is necessary to continue calling upload().  No new data will be
 collected, so nothing new will be uploaded but it is necessary to upload an event telling the
 server this user has opted out.
 @param optedOut YES if the user is opted out, NO otherwise.
 @see isOptedOut
 */
+ (void)setOptedOut:(BOOL)optedOut;

/** Returns whether the Localytics SDK is currently in test mode or not. When in test mode
 a small Localytics tab will appear on the left side of the screen which enables a developer
 to see/test all the campaigns currently available to this customer.
 @return YES if test mode is enabled, NO otherwise
 */
+ (BOOL)isTestModeEnabled;

/** Set whether Localytics SDK should enter test mode or not. When set to YES the a small
 Localytics tab will appear on the left side of the screen, enabling a developer to see/test
 all campaigns currently available to this customer.
 Setting testModeEnabled to NO will cause Localytics to exit test mode, if it's currently
 in it.
 @param enabled Set to YES to enable test mode, NO to disable test mode
 */
+ (void)setTestModeEnabled:(BOOL)enabled;

/** Returns the session time out interval. If a user backgrounds the app and then foregrounds
 the app before the session timeout interval expires then the session will be considered as
 resuming. If the user returns after the time out interval expires the old session willl be
 closed and a new session will be initiated.
 @return the session time out interval (defaults to 15 seconds)
 */
+ (NSTimeInterval)sessionTimeoutInterval;

/** Sets the session time out interval. If a user backgrounds the app and then foregrounds
 the app before the session time out interval expires then the session will be considered as
 resuming. If the user returns after the time out interval expires the old session willl be
 closed and a new session will be initiated.
 @param timeoutInterval The session time out interval
 */
+ (void)setSessionTimeoutInterval:(NSTimeInterval)timeoutInterval;

/** Returns the install id
 @return the install id as an NSString
 */
+ (NSString *)installId;

/** Returns the version of the Localytics SDK
 @return the version of the Localytics SDK as an NSString
 */
+ (NSString *)libraryVersion;

/** Returns the app key currently set in Localytics
 @return the app key currently set in Localytics as an NSString
 */
+ (NSString *)appKey;

/** Returns the analytics API hostname
 @return the analyics API hostname currently set in Localytics as an NSString
 */
+ (NSString *)analyticsHost;

/** Sets the analytics API hostname
 @param analyticsHost The hostname for analytics API requests
 */
+ (void)setAnalyticsHost:(NSString *)analyticsHost;

/** Returns the messaging API hostname
 @return the messaging API hostname currently set in Localytics as an NSString
 */
+ (NSString *)messagingHost;

/** Sets the messaging API hostname
 @param messagingHost The hostname for messaging API requests
 */
+ (void)setMessagingHost:(NSString *)messagingHost;

/** Returns the profiles API hostname
 @return the profiles API hostname currently set in Localytics as an NSString
 */
+ (NSString *)profilesHost;

/** Sets the profiles API hostname
 @param profilesHost The hostname for profiles API requests
 */
+ (void)setProfilesHost:(NSString *)profilesHost;

/** Returns the manifest API hostname
 @return the manifest API hostname currently set in Localytics as an NSString
 */
+ (NSString *)manifestHost;

/** Sets the manifest API hostname
 @param manifestHost The hostname for manifest API requests
 */
+ (void)setManifestHost:(NSString *)manifestHost;

#pragma mark - In-App Message Delegate
/** ---------------------------------------------------------------------------------------
 * @name In-App Message Delegate
 *  ---------------------------------------------------------------------------------------
 */

/** Add a Messaging delegate
 @param delegate An object that implements the LLMessagingDelegate and is called
 when an In-App message will display, did display, will hide, and did hide. Multiple objects
 can be delegates, and each one will receive callbacks.
 @see LLMessagingDelegate
 */
+ (void)addMessagingDelegate:(id<LLMessagingDelegate>)delegate;

/** Remove a Messaging delegate
 @param delegate The delegate previously added that now being removed
 @see LLMessagingDelegate
 */
+ (void)removeMessagingDelegate:(id<LLMessagingDelegate>)delegate;

/** Returns whether the ADID parameter is added to In-App call to action URLs
 @return YES if parameter is added, NO otherwise
 */
+ (BOOL)isInAppAdIdParameterEnabled;

/** Set whether ADID parameter is added to In-App call to action URLs. By default
 the ADID parameter will be added to call to action URLs.
 @param enabled Set to YES to enable the ADID parameter or NO to disable it
 */
+ (void)setInAppAdIdParameterEnabled:(BOOL)enabled;

#pragma mark - Analytics Delegate
/** ---------------------------------------------------------------------------------------
 * @name Analytics Delegate
 *  ---------------------------------------------------------------------------------------
 */

/** Add an Analytics delegate
 @param delegate An object implementing the LLAnalyticsDelegate protocol. Multiple objects
 can be delegates, and each one will receive callbacks.
 @see LLAnalyticsDelegate
 */
+ (void)addAnalyticsDelegate:(id<LLAnalyticsDelegate>)delegate;

/** Remove an Analytics delegate
 @param delegate The delegate previously added that now being removed
 @see LLAnalyticsDelegate
 */
+ (void)removeAnalyticsDelegate:(id<LLAnalyticsDelegate>)delegate;

#pragma mark - WatchKit
/** ---------------------------------------------------------------------------------------
 * @name WatchKit
 *  ---------------------------------------------------------------------------------------
 */

/** Handle calls to the SDK from a WatchKit Extension app

 Call this in the UIApplicationDelegate's application:handleWatchKitExtensionRequest:reply:
 method.

 @param userInfo the userInfo provided by application:handleWatchKitExtensionRequest:reply:
 @param reply The reply provided by application:handleWatchKitExtensionRequest:reply:
 @return YES if the Localytics SDK has handled replying to the WatchKit Extension; NO otherwise
 */
+ (BOOL)handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply;

@end

@protocol LLAnalyticsDelegate <NSObject>
@optional

- (void)localyticsSessionWillOpen:(BOOL)isFirst isUpgrade:(BOOL)isUpgrade isResume:(BOOL)isResume;
- (void)localyticsSessionDidOpen:(BOOL)isFirst isUpgrade:(BOOL)isUpgrade isResume:(BOOL)isResume;

- (void)localyticsDidTagEvent:(NSString *)eventName
                   attributes:(NSDictionary *)attributes
        customerValueIncrease:(NSNumber *)customerValueIncrease;

- (void)localyticsSessionWillClose;

@end

@protocol LLMessagingDelegate <NSObject>
@optional

- (void)localyticsWillDisplayInAppMessage;
- (void)localyticsDidDisplayInAppMessage;
- (void)localyticsWillDismissInAppMessage;
- (void)localyticsDidDismissInAppMessage;

@end

@protocol LLInboxCampaignsRefreshingDelegate <NSObject>
@optional

- (void)localyticsDidBeginRefreshingInboxCampaigns;
- (void)localyticsDidFinishRefreshingInboxCampaigns;

@end

/**
 * A base campaign class containing information relevant to all campaign types
 */
@interface LLCampaignBase : NSObject

/**
 * The unique campaign id.
 */
@property (nonatomic, assign, readonly) NSInteger campaignId;

/**
 * The campaign name
 */
@property (nonatomic, copy, readonly) NSString *name;

/**
 * The attributes associated with the campaign.
 */
@property (nonatomic, copy, readonly) NSDictionary *attributes;

@end

/**
 * A base campaign class containing information relevant to campaigns which
 * include a web component.
 *
 * @see LLInboxCampaign
 */
@interface LLWebViewCampaign : LLCampaignBase
@end

/**
 * The campaign class containing information relevant to a single inbox campaign.
 *
 * @see LLWebViewCampaign
 * @see LLCampaignBase
 */
@interface LLInboxCampaign : LLWebViewCampaign

/**
 * The flag indicating whether the campaign has been read.
 *
 * Note: Changing this value will automatically update the inbox campaign record
 * in the Localytics database.
 */
@property (nonatomic, assign, getter=isRead) BOOL read;

/**
 * The preview title text.
 */
@property (nonatomic, copy, readonly) NSString *titleText;

/**
 * The preview description text.
 */
@property (nonatomic, copy, readonly) NSString *summaryText;

/**
 * The remote url of the thumbnail.
 */
@property (nonatomic, copy, readonly) NSURL *thumbnailUrl;

/**
 * Value indicating if the campaign has a creative.
 */
@property (nonatomic, assign, readonly) BOOL hasCreative;

/**
 * The sort order of the campaign.
 */
@property (nonatomic, assign, readonly) NSInteger sortOrder;

/**
 * The received date of the campaign.
 */
@property (nonatomic, assign, readonly) NSTimeInterval receivedDate;

@end

/**
 * UIViewController class that loads inbox campaigns and displays them in a UITableView.
 * This class also handles marking inbox campaigns as read and displaying the inbox
 * campaign's full creative when it is tapped by pushing an LLInboxDetailViewController
 * onto the UINavigationController stack.
 *
 * By default this class uses custom UITableViewCells which include an unread indicator, title text,
 * summary text (when available), thumbnail image (when available), and created time text.
 *
 * Customization options:
 * - Empty campaigns view, @see property emptyCampaignsView
 * - Show UIActivityIndicatorView while loading campaigns, @see property showsActivityIndicatorView
 * - UITableViewCells, override tableView:cellForRowAtIndexPath:
 * - Full creative display, override tableView:didSelectRowAtIndexPath:, Note: You must also handle
 *   setting the LLInboxCampaign to be read and checking the existense of the creativeUrl property of
 *   the LLInboxCampaign object.
 *
 * @see LLInboxDetailViewController
 */
@interface LLInboxViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, LLInboxCampaignsRefreshingDelegate>

/**
 * The UITableView that shows the inbox campaigns.
 */
@property (nonatomic, strong) UITableView *tableView;

/**
 * The UIView to show when there are no inbox campaigns to display.
 *
 * Note: All subviews of this view should include appropriate Auto Layout constraints because this
 * view's leading edge, top edge, trailing edge, and bottom edge will be constrained to match
 * the main view in LLInboxViewController.
 */
@property (nonatomic, strong) UIView *emptyCampaignsView;

/**
 * Flag indicating whether a UIActivityIndicatorView should be shown will campaigns are loading.
 */
@property (nonatomic, assign) BOOL showsActivityIndicatorView;

/**
 * Flag indicating whether thumbnail images are automatically downloaded and loading into LLInboxThumbnailCell.
 * Defaults to YES. Set this property to NO to manually manage thumbnail downloading and caching (such as through
 * a 3rd party networking library).
 */
@property (nonatomic, assign) BOOL downloadsThumbnails;

/**
 * The font of the UITableViewCell textLabel. Default is 16 point system bold.
 */
@property (nonatomic, strong) UIFont *textLabelFont;

/**
 * The color of the UITableViewCell textLabel. Default is black.
 */
@property (nonatomic, strong) UIColor *textLabelColor;

/**
 * The font of the UITableViewCell detailTextLabel. Default is 14 point system.
 */
@property (nonatomic, strong) UIFont *detailTextLabelFont;

/**
 * The color of the UITableViewCell detailTextLabel. Default is black.
 */
@property (nonatomic, strong) UIColor *detailTextLabelColor;

/**
 * The font of the UITableViewCell timeTextLabel. Default is 10 point system.
 */
@property (nonatomic, strong) UIFont *timeTextLabelFont;

/**
 * The color of the UITableViewCell timeTextLabel. Default is gray.
 */
@property (nonatomic, strong) UIColor *timeTextLabelColor;

/**
 * The color of the UITableViewCell unread indicator. Default is #007AFF.
 */
@property (nonatomic, strong) UIColor *unreadIndicatorColor;

/**
 * The color of the UITablviewCell background
 */
@property (nonatomic, strong) UIColor *cellBackgroundColor;

/**
 * The UIView to show when a creative fails to load in a detail view. This property is used to set the
 * creativeLoadErrorView of LLInboxDetailViewControllers created when the user opens a campaign.
 * If this property is not set, a gray 'X' will be shown in the center of the view.
 *
 * Note: All subviews of this view should include appropriate Auto Layout constraints because this
 * view's leading edge, top edge, trailing edge, and bottom edge will be constrained to match
 * the main view in LLInboxDetailViewController.
 */
@property (nonatomic, strong) UIView *creativeLoadErrorView;

/**
 * Returns the inbox campaign for an index path (useful for overriding tableView:cellForRowAtIndexPath:)
 *
 * @return An LLInboxCampaign object for the index path.
 */
- (LLInboxCampaign *)campaignForRowAtIndexPath:(NSIndexPath *)indexPath;

@end

/**
 * UIViewController class that displays an inbox campaign's full creative. This class also handles tagging
 * impression events when a call to action is tapped within the creative or when the UIViewController is
 * dismissed.
 *
 * Customization options:
 * - Error view, @see errorView
 *
 * @see LLInboxViewController
 */
@interface LLInboxDetailViewController : UIViewController

/**
 * The inbox campaign being displayed
 */
@property (nonatomic, strong, readonly) LLInboxCampaign *campaign;

/**
 * The UIView to show when the full creative fails to load. If this property is not set, a gray 'X' will
 * be shown in the center of the view.
 *
 * Note: All subviews of this view should include appropriate Auto Layout constraints because this
 * view's leading edge, top edge, trailing edge, and bottom edge will be constrained to match
 * the main view in LLInboxDetailViewController.
 */
@property (nonatomic, strong) UIView *creativeLoadErrorView;

@end


text:
using NUnit.Framework;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.UI;

namespace osu.Game.Tests.Visual.UserInterface
{
    public class TestSceneModIcon : OsuTestScene
    {
        [Test]
        public void TestChangeModType()
        {
            ModIcon icon = null;

            AddStep("create mod icon", () => Child = icon = new ModIcon(new OsuModDoubleTime()));
            AddStep("change mod", () => icon.Mod = new OsuModEasy());
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
package com.devsh.androidlogin.feed.model;

public class Comment {
    private String id;
    private String username;
    private String user_profile_image_url;
    private String user_message;
    private boolean owner;

    public String getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getUser_profile_image_url() {
        return user_profile_image_url;
    }

    public String getUser_message() {
        return user_message;
    }

    public boolean getOwner() {
        return owner;
    }

}


text:
package blended.launcher.jvmrunner

import blended.testsupport.scalatest.LoggingFreeSpec
import org.scalatest.matchers.should.Matchers

class RunningProcessSpec extends LoggingFreeSpec
  with Matchers {

  "A RunningProcess should" - {
    pending
  }
}


text:
@implementation NTESDemoFetchChatroomTask
- (NSURLRequest *)taskRequest
{
    NSString *urlString = [[[NTESDemoConfig sharedConfig] apiURL] stringByAppendingString:@"/chatroom/homeList"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
    [request setHTTPMethod:@"GET"];
    [request addValue:[NTESDemoConfig sharedConfig].appKey forHTTPHeaderField:@"appkey"];
    [request addValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    return request;

}

- (void)onGetResponse:(id)jsonObject
                error:(NSError *)error
{
    NSMutableArray *chatrooms = nil;
    NSError *resultError = error;

    if (error == nil && [jsonObject isKindOfClass:[NSDictionary class]])
    {
        NSDictionary *dict = (NSDictionary *)jsonObject;
        NSInteger code = [dict jsonInteger:@"res"];
        resultError = code == 200 ? nil : [NSError errorWithDomain:@"ntes domain"
                                                              code:code
                                                          userInfo:nil];
        if (resultError == nil)
        {
            chatrooms = [NSMutableArray array];
            NSDictionary *msg = [dict jsonDict:@"msg"];
            NSArray *list = [msg jsonArray:@"list"];
            for (NSDictionary *item in list) {
                NIMChatroom *chatroom = [NTESChatroomMaker makeChatroom:item];
                if (chatroom)
                {
                    [chatrooms addObject:chatroom];
                }
            }
        }
    }

    if (_handler) {
        _handler(resultError,chatrooms);
    }

}
@end


text:
#ifndef __COMMON_TYPES_H
#define __COMMON_TYPES_H

#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif

#ifndef _7ZIP_INT16_DEFINED
#define _7ZIP_INT16_DEFINED
typedef short Int16;
#endif

#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif

#ifndef _7ZIP_INT32_DEFINED
#define _7ZIP_INT32_DEFINED
typedef int Int32;
#endif

#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
typedef unsigned int UInt32;
#endif

#ifdef _MSC_VER

#ifndef _7ZIP_INT64_DEFINED
#define _7ZIP_INT64_DEFINED
typedef __int64 Int64;
#endif

#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
typedef unsigned __int64 UInt64;
#endif

#else

#ifndef _7ZIP_INT64_DEFINED
#define _7ZIP_INT64_DEFINED
typedef long long int Int64;
#endif

#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
typedef unsigned long long int UInt64;
#endif

#endif

#endif


text:
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.GamerServices;

namespace Pinball
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game : Microsoft.Xna.Framework.Game
    {
        #region Fields

        readonly GraphicsDeviceManager graphics;

        readonly ScreenManager screenManager;
        readonly SoundManager soundPlayer;
        readonly StorageManager storageManager;
        readonly World world;

        #endregion

        #region Initialization

        /// <summary>
        /// The main game constructor.
        /// </summary>
        public Game()
        {
            Content.RootDirectory = "Content";

            graphics = new GraphicsDeviceManager(this);

            graphics.PreferredBackBufferWidth = 480;
            graphics.PreferredBackBufferHeight = 800;

            // Create the screen manager and sound effect player component
            screenManager = new ScreenManager(this);
            soundPlayer = new SoundManager(this);
            storageManager = new StorageManager(this);
            world = new World(this);

            Components.Add(screenManager);
            Components.Add(soundPlayer);
            Components.Add(storageManager);
            Components.Add(world);

            // Load the game data
            StorageManager.LoadGameData();

            // Activate the first screens.
            screenManager.AddScreen(new GameplayScreen());
            //screenManager.AddScreen(new BackgroundScreen());
            //screenManager.AddScreen(new MainMenuScreen());
        }

        #endregion

        #region Draw

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.Black);

            // The real drawing happens inside the screen manager component.
            base.Draw(gameTime);
        }

        #endregion
    }
}


text:
class Company < ActiveRecord::Base
	has_many :company_projects
	has_many :projects, through: :company_projects
	has_many :products
	has_many :users
end


text:
package jatoo.resources;

import java.awt.Image;

import javax.swing.ImageIcon;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This class ease the work with images, offering also the possibility to have a
 * fallback (very useful for example when a project extends another project).
 *
 * @author Cristian Sulea
 * @version 1.1, October 10, 2016
 */
public final class ResourcesImages {

  /** The logger. */
  private final Log logger;

  /** The class that will provide the base name. */
  private final Class<?> clazz;

  /** The fallback to be used when a resource is not found. */
  private final ResourcesImages fallback;

  /**
   * Creates a {@link ResourcesImages} object using as base name the package of
   * the specified class.
   *
   * @param clazz
   *          the class that will provide the base name
   */
  public ResourcesImages(final Class<?> clazz) {
    this(clazz, (ResourcesImages) null);
  }

  /**
   * Creates a {@link ResourcesImages} object using as base name the package of
   * the specified class. If a resource is not found, the fallback will be used
   * before returning.
   *
   * @param clazz
   *          the class that will provide the base name
   * @param fallback
   *          the class to be used to create the {@link ResourcesImages} to be
   *          used in case a resource is not found in this one
   */
  public ResourcesImages(final Class<?> clazz, final Class<?> fallback) {
    this(clazz, new ResourcesImages(fallback));
  }

  /**
   * Creates a {@link ResourcesImages} object using as base name the package of
   * the specified class. If a resource is not found, the fallback will be used
   * before returning.
   *
   * @param clazz
   *          the class that will provide the base name
   * @param fallback
   *          the {@link ResourcesImages} to be used in case a resource is not
   *          found in this one
   */
  public ResourcesImages(final Class<?> clazz, final ResourcesImages fallback) {

    logger = LogFactory.getLog(clazz);

    this.clazz = clazz;
    this.fallback = fallback;
  }

  /**
   * Gets the {@link ImageIcon} with the given name. If the icon was not found,
   * the fallback (if it was provided) will be used.
   *
   * @param name
   *          the name of the desired icon
   *
   * @return the icon with the given name, o null if the icon was
   *         not found
   */
  public ImageIcon getImageIcon(final String name) {

    ImageIcon icon;

    try {
      icon = new ImageIcon(clazz.getResource(name));
    }

    catch (Exception e) {

      if (fallback != null) {
        icon = fallback.getImageIcon(name);
      }

      else {
        icon = null;
        logger.error("no image icon #" + name);
      }
    }

    return icon;
  }

  /**
   * Gets the {@link Image} with the given name. If the image was not found, the
   * fallback (if it was provided) will be used.
   *
   * @param name
   *          the name of the desired image
   *
   * @return the icon with the given name, o null if the icon was
   *         not found
   */
  public Image getImage(final String name) {

    Image image;

    try {
      image = new ImageIcon(clazz.getResource(name)).getImage();
    }

    catch (Exception e) {

      if (fallback != null) {
        image = fallback.getImage(name);
      }

      else {
        image = null;
        logger.error("no image #" + name);
      }
    }

    return image;
  }

}


text:
class EdgeSort(object):
    DIRECT_JUMP = 0
    TRUE_BRANCH = 1
    FALSE_BRANCH = 2
    BACK_EDGE = 3

class Edge(object):
    def __init__(self, src, dst):

        self.src = src
        self.dst = dst

        self.start_index = None
        self.max_start_index = None
        self.end_index = None
        self.max_end_index = None

        self.points = [ ]
        self.moves = [ ]
        self.coordinates = [ ]
        self.sort = EdgeSort.DIRECT_JUMP

    def add_point(self, col, row, index):
        self.points.append((col, row, index))

    def add_move(self, move):
        self.moves.append(move)

    def add_coordinate(self, x, y):
        if len(self.coordinates) >= 2:
            coord_a, coord_b = self.coordinates[-2], self.coordinates[-1]
            if coord_b[0] == coord_a[0] == x:
                # it moves vertically
                # replace coord_b
                self.coordinates[-1] = (x, y)
                return
            elif coord_b[1] == coord_a[1] == y:
                # it moves horizontally
                # replace coord b
                self.coordinates[-1] = (x, y)
                return

        self.coordinates.append((x, y))

    @property
    def first_move(self):
        if self.moves:
            return self.moves[0]

        return 1  # NO_MOVE

    @property
    def last_move(self):
        if self.moves:
            return self.moves[-1]

        return 1  # NO_MOVE

    def __repr__(self):
        return "<Edge between %s and %s, %d coordinates>" % (self.src, self.dst, len(self.coordinates))


text:
package test

import com.sun.jdi.request.ClassUnloadRequest
import org.scaladebugger.api.lowlevel.classes.{ClassUnloadManager, ClassUnloadRequestInfo}
import org.scaladebugger.api.lowlevel.requests.JDIRequestArgument

import scala.util.Try

/**
 * Test class unload manager that merely invokes the provided
 * class unload manager underneath to make it easier to mock.
 *
 * @param classUnloadManager The underlying class unload manager used to
 *                            execute all methods
 */
class TestClassUnloadManager(
  private val classUnloadManager: ClassUnloadManager
) extends ClassUnloadManager {
  override def classUnloadRequestList: Seq[String] =
    classUnloadManager.classUnloadRequestList
  override def hasClassUnloadRequest(id: String): Boolean =
    classUnloadManager.hasClassUnloadRequest(id)
  override def getClassUnloadRequest(id: String): Option[ClassUnloadRequest] =
    classUnloadManager.getClassUnloadRequest(id)
  override def createClassUnloadRequestWithId(requestId: String, extraArguments: JDIRequestArgument*): Try[String] =
    classUnloadManager.createClassUnloadRequestWithId(requestId, extraArguments: _*)
  override def removeClassUnloadRequest(id: String): Boolean =
    classUnloadManager.removeClassUnloadRequest(id)
  override def getClassUnloadRequestInfo(id: String): Option[ClassUnloadRequestInfo] =
    classUnloadManager.getClassUnloadRequestInfo(id)
}


text:
import '../../bootstrap/_button-group.scss'
import '../../bootstrap/_buttons.scss'


text: ASP.NET Web app that stores information about bus schedules, shops and other stuff with open API


text:
<?php

namespace Elcodi\Bundle\CartCouponBundle\DependencyInjection;

use Symfony\Component\Config\Definition\ConfigurationInterface;

use Elcodi\Bundle\CoreBundle\DependencyInjection\Abstracts\AbstractExtension;
use Elcodi\Bundle\CoreBundle\DependencyInjection\Interfaces\EntitiesOverridableExtensionInterface;

/**
 * Class ElcodiCartCouponExtension
 */
class ElcodiCartCouponExtension extends AbstractExtension implements EntitiesOverridableExtensionInterface
{
    /**
     * @var string
     *
     * Extension name
     */
    const EXTENSION_NAME = 'elcodi_cart_coupon';

    /**
     * Get the Config file location
     *
     * @return string Config file location
     */
    public function getConfigFilesLocation()
    {
        return __DIR__ . '/../Resources/config';
    }

    /**
     * Return a new Configuration instance.
     *
     * If object returned by this method is an instance of
     * ConfigurationInterface, extension will use the Configuration to read all
     * bundle config definitions.
     *
     * Also will call getParametrizationValues method to load some config values
     * to internal parameters.
     *
     * @return ConfigurationInterface Configuration file
     */
    protected function getConfigurationInstance()
    {
        return new Configuration(static::EXTENSION_NAME);
    }

    /**
     * Load Parametrization definition
     *
     * return array(
     *      'parameter1' => $config['parameter1'],
     *      'parameter2' => $config['parameter2'],
     *      ...
     * );
     *
     * @param array $config Bundles config values
     *
     * @return array Parametrization values
     */
    protected function getParametrizationValues(array $config)
    {
        return [
            "elcodi.entity.cart_coupon.class" => $config['mapping']['cart_coupon']['class'],
            "elcodi.entity.cart_coupon.mapping_file" => $config['mapping']['cart_coupon']['mapping_file'],
            "elcodi.entity.cart_coupon.manager" => $config['mapping']['cart_coupon']['manager'],
            "elcodi.entity.cart_coupon.enabled" => $config['mapping']['cart_coupon']['enabled'],

            "elcodi.entity.order_coupon.class" => $config['mapping']['order_coupon']['class'],
            "elcodi.entity.order_coupon.mapping_file" => $config['mapping']['order_coupon']['mapping_file'],
            "elcodi.entity.order_coupon.manager" => $config['mapping']['order_coupon']['manager'],
            "elcodi.entity.order_coupon.enabled" => $config['mapping']['order_coupon']['enabled'],
        ];
    }

    /**
     * Config files to load
     *
     * return array(
     *      'file1.yml',
     *      'file2.yml',
     *      ...
     * );
     *
     * @param array $config Config
     *
     * @return array Config files
     */
    public function getConfigFiles(array $config)
    {
        return [
            'services',
            'eventListeners',
            'factories',
            'services',
            'repositories',
            'eventDispatchers',
            'objectManagers',
            'directors',
        ];
    }

    /**
     * Get entities overrides.
     *
     * Result must be an array with:
     * index: Original Interface
     * value: Parameter where class is defined.
     *
     * @return array Overrides definition
     */
    public function getEntitiesOverrides()
    {
        return [
            'Elcodi\Component\CartCoupon\Entity\Interfaces\CartCouponInterface' => 'elcodi.entity.cart_coupon.class',
            'Elcodi\Component\CartCoupon\Entity\Interfaces\OrderCouponInterface' => 'elcodi.entity.order_coupon.class',
        ];
    }

    /**
     * Returns the extension alias, same value as extension name
     *
     * @return string The alias
     */
    public function getAlias()
    {
        return static::EXTENSION_NAME;
    }
}


text:
myNS.initialize = function() {
	var scope = {
		map: null,
		service: null,
		state: {
			// Mapped by place name according to autocomplete label
			searchResultPlaceDetail: {}
		}
	};

	this.map.initialize(scope);
	this.autocomplete.initialize(scope);
	this.calculate.initializeButtons(scope);
}


text:
<?php

namespace Maghead\Generator\Schema;

use RuntimeException;
use CodeGen\ClassFile;
use Maghead\Schema\Schema;
use Maghead\Schema\DeclareSchema;
use Maghead\Schema\BaseSchema;
use Maghead\Generator\Schema\BaseModelClassGenerator;
use Maghead\Generator\Schema\BaseRepoClassGenerator;
use Maghead\Generator\Schema\BaseCollectionClassGenerator;
use Maghead\Generator\Schema\CollectionClassGenerator;
use Maghead\Generator\Schema\ModelClassGenerator;
use Maghead\Generator\Schema\RepoClassGenerator;
use Maghead\Generator\Schema\SchemaProxyClassGenerator;
use Maghead\Runtime\Config\Config;
use Maghead\Runtime\Repo;
use Maghead\Runtime\Model;
use Maghead\Runtime\Collection;

/**
 * Builder for building static schema class file.
 */
class SchemaGenerator
{
    protected $config;

    protected $forceUpdate = false;

    public function __construct(Config $config)
    {
        $this->config = $config;
    }

    public function setForceUpdate($force = true)
    {
        $this->forceUpdate = $force;
    }

    protected function getBaseModelClass()
    {
        if ($this->config) {
            return $this->config->getBaseModelClass();
        }

        return Model::class;
    }

    protected function getBaseCollectionClass()
    {
        if ($this->config) {
            return $this->config->getBaseCollectionClass();
        }

        return Collection::class;
    }

    /**
     * This method checks the exising schema file and the generated class file mtime.
     * If the schema file is newer or the forceUpdate flag is specified, then
     * the generated class files should be updated.
     *
     * @param CodeGen\ClassFile $cTemplate
     * @param DeclareSchema           $schema
     */
    protected function updateClassFile(ClassFile $cTemplate, DeclareSchema $schema, $canOverwrite = false)
    {
        // always update the proxy schema file
        $classFilePath = $schema->getRelatedClassPath($cTemplate->getShortClassName());

        // classes not Model/Collection class are overwriteable
        if (file_exists($classFilePath)) {
            if ($canOverwrite && ($schema->isNewerThanFile($classFilePath || $this->forceUpdate))) {
                $this->writeClassTemplateToPath($cTemplate, $classFilePath);

                return [$cTemplate->getClassName(), $classFilePath];
            }
        } else {
            if ($this->writeClassTemplateToPath($cTemplate, $classFilePath)) {
                return [$cTemplate->getClassName(), $classFilePath];
            }
        }
    }

    /**
     * Generate modal class file, don't overwrite by default.
     *
     * @param Schema $schema
     * @param bool   $force  = true
     */
    public function generateModelClass(DeclareSchema $schema)
    {
        $cTemplate = ModelClassGenerator::create($schema);

        return $this->updateClassFile($cTemplate, $schema, false); // do not overwrite
    }

    /**
     * Generate repo class file, don't overwrite by default.
     *
     * @param Schema $schema
     * @param bool   $force  = true
     */
    public function generateRepoClass(DeclareSchema $schema)
    {
        $cTemplate = RepoClassGenerator::create($schema);

        return $this->updateClassFile($cTemplate, $schema, false); // do not overwrite
    }

    /**
     * Generate collection class from a schema object.
     *
     * @param DeclareSchema $schema
     *
     * @return array class name, class file path
     */
    public function generateCollectionClass(DeclareSchema $schema)
    {
        $cTemplate = CollectionClassGenerator::create($schema);

        return $this->updateClassFile($cTemplate, $schema, false);
    }

    /**
     * Write class template to the schema directory.
     *
     * @param string $directory The schema class directory.
     * @param CodeGen\ClassFile class template object.
     * @param bool $overwrite Overwrite class file.
     *
     * @return array
     */
    protected function writeClassTemplateToPath(ClassFile $cTemplate, string $filepath)
    {
        if (false === file_put_contents($filepath, $cTemplate->render())) {
            throw RuntimeException("Can not write file $filepath");
        }

        return true;
    }

    public function generateSchemaFiles(DeclareSchema $schema)
    {
        $classMap = array();
        $cTemplates = array();

        // always update schema proxy and base classes
        $cTemplates[] = SchemaProxyClassGenerator::create($schema);
        $cTemplates[] = BaseModelClassGenerator::create($schema, $this->getBaseModelClass());
        $cTemplates[] = BaseRepoClassGenerator::create($schema, Repo::class);
        $cTemplates[] = BaseCollectionClassGenerator::create($schema, $this->getBaseCollectionClass());
        foreach ($cTemplates as $cTemplate) {
            if ($result = $this->updateClassFile($cTemplate, $schema, true)) {
                list($className, $classFile) = $result;
                $classMap[ $className ] = $classFile;
            }
        }

        if ($result = $this->generateCollectionClass($schema)) {
            list($className, $classFile) = $result;
            $classMap[ $className ] = $classFile;
        }
        if ($result = $this->generateModelClass($schema)) {
            list($className, $classFile) = $result;
            $classMap[ $className ] = $classFile;
        }
        if ($result = $this->generateRepoClass($schema)) {
            list($className, $classFile) = $result;
            $classMap[ $className ] = $classFile;
        }

        return $classMap;
    }

    /**
     * Given a schema class list, generate schema files.
     *
     * @param array $classes class list or schema object list.
     *
     * @return array class map array of schema class and file path.
     */
    public function generate($schemas)
    {
        // class map [ class => class file path ]
        $classMap = [];
        foreach ($schemas as $schema) {
            if ($schema->virtual) {
                continue;
            }

            $generated = $this->generateSchemaFiles($schema);
            if (!empty($generated)) {
                $classMap = array_merge($classMap, $generated);
            }
        }

        return $classMap;
    }
}


text:
TableSchema::~TableSchema()
{
	for (TableColumn * tblcol : _columns) {
		delete tblcol;
	}
}

TableSchema::ErrorCode
TableSchema::AddColumn(const std::string& name, const std::string& srctype, const std::string& mdstype)
{
	if (! _legal_types.count(srctype)) return BadSrcType;
	if (! _legal_mdstypes.count(mdstype)) return BadMdsType;

	for (TableColumn * tblcol : _columns) {
		if (tblcol->Name() == name) return DupeColumn;
	}

	typeconverter_t converter;
	if (! Engine::GetEngine()->GetConverter(srctype, mdstype, converter)) {
		return NoConverter;
	}

	auto newcolumn = new TableColumn(name, mdstype, converter);
	_columns.push_back(newcolumn);
	return Ok;
}

void
TableSchema::PushColumnInfo(std::back_insert_iterator<std::vector<std::pair<std::string, std::string> > > inserter)
const
{
	for (const auto & tblcol : _columns) {
		*(inserter++) = std::make_pair(tblcol->Name(), tblcol->MdsType());
	}
}

std::set<std::string> TableSchema::_legal_types = {
	"bool",
	"int",
	"str",
	"double",
	"int-timet",
	"double-timet",
	"str-rfc3339",
	"str-rfc3194"
};

std::set<std::string> TableSchema::_legal_mdstypes = {
	"mt:bool",
	"mt:wstr",
	"mt:float64",
	"mt:int32",
	"mt:int64",
	"mt:utc"
};

// vim: se sw=8 :


text:
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE project SYSTEM "../config/MyWebTest.dtd">

<project name="testPdfFonts" default="allTests" basedir=".">

    <target name="allTests" depends="testFonts, testFontsFilter"/>

    <target name="testFonts">
        <webtest name="pdfFonts: confirm existence of PDF fonts">
            &sharedConfiguration;
            <steps>
                <invoke url="testDocFonts.pdf"/>
                <pdfVerifyFont name="times-roman" type="type1"/>
                <not description="expected to fail: wrong case">
                    <pdfVerifyFont name="times-roman" matchCase="true"/>
                </not>
                <pdfVerifyFont page="2" name="ComicSansMS-Bold"/>
                <pdfVerifyFont page="2" type="TrueType"/>
                <pdfVerifyFont page="2" name="ComicSansMS-Bold" type="TrueType"/>
                <not description="expect to fail: incorrect page">
                    <pdfVerifyFont page="1" name="ComicSansMS-Bold"/>
                </not>
                <not description="expect to fail: incorrect type">
                    <pdfVerifyFont name="ComicSansMS-Bold" type="Type1"/>
                </not>
                <not description="expect to fail: unknown font">
                    <pdfVerifyFont name="invisible font"/>
                </not>
            </steps>
        </webtest>
    </target>

    <target name="testFontsFilter">
        <webtest name="pdfFonts: confirm verifyContent extracting font information">
            &sharedConfiguration;
            <steps>
                <invoke url="testDocFonts.pdf"/>
                <verifyContent readFiltered="false" referenceFile="verifyContent/expectedPdfFonts.txt">
                    <pdfToFontsFilter description="extract PDF font information"/>
                    <lineSeparatorFilter description="normalise line separators"/>
                </verifyContent>
            </steps>
        </webtest>
    </target>

</project>


text:
#include "SearchParams.h"

#ifdef SMTYPE_CHECKING
// slower program, compile time type checking

bool StringMatchingT::operator==( const StringMatchingT &rhs ) const {
  if ( param == rhs.getSMIntParam() ) {
    return true;
  } else {
    return false;
  }
};

bool StringPartT::operator==( const StringPartT &rhs ) const {
  if ( param == rhs.getSMIntParam() ) {
    return true;
  } else {
    return false;
  }
};

bool SortingT::operator==( const SortingT &rhs ) const {
  if ( param == rhs.getSMIntParam() ) {
    return true;
  } else {
    return false;
  }
};
#endif


text:
//-----------------------------------------------------------------------
// <copyright file="PersistenceSpec.cs" company="Akka.NET Project">
//     Copyright (C) 2009-2016 Typesafe Inc. <http://www.typesafe.com>
//     Copyright (C) 2013-2016 Akka.NET project <https://github.com/akkadotnet/akka.net>
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Akka.Configuration;
using Akka.TestKit;
using Akka.Util.Internal;
using Xunit.Abstractions;

namespace Akka.Persistence.Tests
{
    public abstract class PersistenceSpec : AkkaSpec
    {
        public static Config Configuration(string test, string serialization = null,
            string extraConfig = null)
        {
            var c = extraConfig == null
                ? ConfigurationFactory.Empty
                : ConfigurationFactory.ParseString(extraConfig);
            var configString = string.Format(@"
                akka.actor.serialize-creators = {0}
                akka.actor.serialize-messages = {0}
                akka.persistence.publish-plugin-commands = on
                akka.persistence.snapshot-store.local.dir = ""target/snapshots-{1}/""
                akka.test.single-expect-default = 10s", serialization ?? "on", test);

            return c.WithFallback(ConfigurationFactory.ParseString(configString));
        }

        internal readonly Cleanup Clean;

        private readonly AtomicCounter _counter = new AtomicCounter(0);

        private readonly string _name;

        protected PersistenceSpec(string config, ITestOutputHelper output = null)
            : base(config, output)
        {
            _name = NamePrefix + "-" + _counter.GetAndIncrement();
            Clean = new Cleanup(this);
            Clean.Initialize();
        }

        protected PersistenceSpec(Config config = null, ITestOutputHelper output = null)
            : base(config, output)
        {
            _name = NamePrefix + "-" + _counter.GetAndIncrement();
            Clean = new Cleanup(this);
            Clean.Initialize();
        }

        public PersistenceExtension Extension { get { return Persistence.Instance.Apply(Sys); } }

        public string NamePrefix { get { return Sys.Name; } }
        public string Name { get { return _name; } }

        protected override void AfterAll()
        {
            base.AfterAll();
            Clean.Dispose();
        }

        protected void ExpectMsgInOrder(params object[] ordered)
        {
            var msg = ExpectMsg<object[]>();
            msg
                //.Select(x => x.ToString())
                .ShouldOnlyContainInOrder(ordered);
        }
    }

    internal class Cleanup : IDisposable
    {
        internal List<DirectoryInfo> StorageLocations;
        private static readonly object _syncRoot = new object();

        public Cleanup(AkkaSpec spec)
        {
            StorageLocations = new[]
            {
                "akka.persistence.snapshot-store.local.dir"
            }.Select(s => new DirectoryInfo(spec.Sys.Settings.Config.GetString(s))).ToList();
        }

        public void Initialize()
        {
            DeleteStorageLocations();
        }

        private void DeleteStorageLocations()
        {
            StorageLocations.ForEach(fi =>
            {
                lock (_syncRoot)
                {
                    try
                    {
                        if (fi.Exists) fi.Delete(true);
                    }
                    catch (IOException) { }
                }
            });
        }

        public void Dispose()
        {
            DeleteStorageLocations();
        }
    }

    public abstract class NamedPersistentActor : PersistentActor
    {
        private readonly string _name;

        protected NamedPersistentActor(string name)
        {
            _name = name;
        }

        public override string PersistenceId
        {
            get { return _name; }
        }
    }

    internal sealed class GetState
    {
        public static readonly GetState Instance = new GetState();
        private GetState() { }
    }

    internal class TestException : Exception
    {
        public TestException(string message)
            : base(message)
        {
        }
    }
}


text:
/**
 */
package de.uni_hildesheim.sse.vil.templatelang.templateLang;

import org.eclipse.emf.ecore.EFactory;

/**
 *
 * The Factory for the model.
 * It provides a create method for each non-abstract class of the model.
 *
 * @see de.uni_hildesheim.sse.vil.templatelang.templateLang.TemplateLangPackage
 * @generated
 */
public interface TemplateLangFactory extends EFactory
{
  /**
   * The singleton instance of the factory.
   *
   *
   * @generated
   */
  TemplateLangFactory eINSTANCE = de.uni_hildesheim.sse.vil.templatelang.templateLang.impl.TemplateLangFactoryImpl.init();

  /**
   * Returns a new object of class 'Language Unit'.
   *
   *
   * @return a new object of class 'Language Unit'.
   * @generated
   */
  LanguageUnit createLanguageUnit();

  /**
   * Returns a new object of class 'Top'.
   *
   *
   * @return a new object of class 'Top'.
   * @generated
   */
  Top createTop();

  /**
   * Returns a new object of class 'Hinted Expression'.
   *
   *
   * @return a new object of class 'Hinted Expression'.
   * @generated
   */
  HintedExpression createHintedExpression();

  /**
   * Returns a new object of class 'Indentation Hint'.
   *
   *
   * @return a new object of class 'Indentation Hint'.
   * @generated
   */
  IndentationHint createIndentationHint();

  /**
   * Returns a new object of class 'Indentation Hint Part'.
   *
   *
   * @return a new object of class 'Indentation Hint Part'.
   * @generated
   */
  IndentationHintPart createIndentationHintPart();

  /**
   * Returns a new object of class 'Formatting Hint'.
   *
   *
   * @return a new object of class 'Formatting Hint'.
   * @generated
   */
  FormattingHint createFormattingHint();

  /**
   * Returns a new object of class 'Formatting Hint Part'.
   *
   *
   * @return a new object of class 'Formatting Hint Part'.
   * @generated
   */
  FormattingHintPart createFormattingHintPart();

  /**
   * Returns a new object of class 'Vil Def'.
   *
   *
   * @return a new object of class 'Vil Def'.
   * @generated
   */
  VilDef createVilDef();

  /**
   * Returns a new object of class 'Stmt Block'.
   *
   *
   * @return a new object of class 'Stmt Block'.
   * @generated
   */
  StmtBlock createStmtBlock();

  /**
   * Returns a new object of class 'Stmt'.
   *
   *
   * @return a new object of class 'Stmt'.
   * @generated
   */
  Stmt createStmt();

  /**
   * Returns a new object of class 'Alternative'.
   *
   *
   * @return a new object of class 'Alternative'.
   * @generated
   */
  Alternative createAlternative();

  /**
   * Returns a new object of class 'Content'.
   *
   *
   * @return a new object of class 'Content'.
   * @generated
   */
  Content createContent();

  /**
   * Returns a new object of class 'Switch'.
   *
   *
   * @return a new object of class 'Switch'.
   * @generated
   */
  Switch createSwitch();

  /**
   * Returns a new object of class 'Switch Part'.
   *
   *
   * @return a new object of class 'Switch Part'.
   * @generated
   */
  SwitchPart createSwitchPart();

  /**
   * Returns a new object of class 'Loop'.
   *
   *
   * @return a new object of class 'Loop'.
   * @generated
   */
  Loop createLoop();

  /**
   * Returns a new object of class 'While'.
   *
   *
   * @return a new object of class 'While'.
   * @generated
   */
  While createWhile();

  /**
   * Returns a new object of class 'multiselect'.
   *
   *
   * @return a new object of class 'multiselect'.
   * @generated
   */
  multiselect createmultiselect();

  /**
   * Returns a new object of class 'generic Multiselect'.
   *
   *
   * @return a new object of class 'generic Multiselect'.
   * @generated
   */
  genericMultiselect creategenericMultiselect();

  /**
   * Returns a new object of class 'multi Select Part'.
   *
   *
   * @return a new object of class 'multi Select Part'.
   * @generated
   */
  multiSelectPart createmultiSelectPart();

  /**
   * Returns a new object of class 'user Multiselect'.
   *
   *
   * @return a new object of class 'user Multiselect'.
   * @generated
   */
  userMultiselect createuserMultiselect();

  /**
   * Returns a new object of class 'Extension'.
   *
   *
   * @return a new object of class 'Extension'.
   * @generated
   */
  Extension createExtension();

  /**
   * Returns a new object of class 'Java Qualified Name'.
   *
   *
   * @return a new object of class 'Java Qualified Name'.
   * @generated
   */
  JavaQualifiedName createJavaQualifiedName();

  /**
   * Returns the package supported by this factory.
   *
   *
   * @return the package supported by this factory.
   * @generated
   */
  TemplateLangPackage getTemplateLangPackage();

} //TemplateLangFactory


text:
package com.redhat.ceylon.compiler.java.runtime.metamodel;

import java.util.List;

import ceylon.language.Anything;
import ceylon.language.Iterator;
import ceylon.language.Sequential;
import ceylon.language.empty_;
import ceylon.language.finished_;
import ceylon.language.meta.declaration.FunctionDeclaration$impl;
import ceylon.language.meta.declaration.FunctionalDeclaration;
import ceylon.language.meta.declaration.OpenType;

import com.redhat.ceylon.compiler.java.Util;
import com.redhat.ceylon.compiler.java.metadata.Ceylon;
import com.redhat.ceylon.compiler.java.metadata.Defaulted;
import com.redhat.ceylon.compiler.java.metadata.Ignore;
import com.redhat.ceylon.compiler.java.metadata.Name;
import com.redhat.ceylon.compiler.java.metadata.Sequenced;
import com.redhat.ceylon.compiler.java.metadata.TypeInfo;
import com.redhat.ceylon.compiler.java.metadata.TypeParameter;
import com.redhat.ceylon.compiler.java.metadata.TypeParameters;
import com.redhat.ceylon.compiler.java.metadata.Variance;
import com.redhat.ceylon.compiler.java.runtime.model.TypeDescriptor;
import com.redhat.ceylon.compiler.typechecker.model.Functional;
import com.redhat.ceylon.compiler.typechecker.model.Method;
import com.redhat.ceylon.compiler.typechecker.model.Parameter;
import com.redhat.ceylon.compiler.typechecker.model.ParameterList;
import com.redhat.ceylon.compiler.typechecker.model.ProducedType;
import com.redhat.ceylon.compiler.typechecker.model.ProducedTypedReference;
import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration;

@Ceylon(major = 7)
@com.redhat.ceylon.compiler.java.metadata.Class
public class FreeFunction
    extends FreeFunctionOrValue
    implements ceylon.language.meta.declaration.FunctionDeclaration, AnnotationBearing {

    @Ignore
    public static final TypeDescriptor $TypeDescriptor$ = TypeDescriptor.klass(FreeFunction.class);

    private Sequential<? extends ceylon.language.meta.declaration.TypeParameter> typeParameters;

    private OpenType type;

    private Sequential<? extends ceylon.language.meta.declaration.FunctionOrValueDeclaration> parameterList;

    public FreeFunction(com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration declaration) {
        super(declaration);

        // FIXME: make lazy
        // FIXME: share with ClassOrInterface
        List<com.redhat.ceylon.compiler.typechecker.model.TypeParameter> typeParameters = ((Functional) declaration).getTypeParameters();
        ceylon.language.meta.declaration.TypeParameter[] typeParametersArray = new ceylon.language.meta.declaration.TypeParameter[typeParameters.size()];
        int i=0;
        for(com.redhat.ceylon.compiler.typechecker.model.TypeParameter tp : typeParameters){
            typeParametersArray[i++] = new com.redhat.ceylon.compiler.java.runtime.metamodel.FreeTypeParameter(tp);
        }
        this.typeParameters = Util.sequentialWrapper(ceylon.language.meta.declaration.TypeParameter.$TypeDescriptor$, typeParametersArray);

        this.type = Metamodel.getMetamodel(declaration.getType());
        this.parameterList = FunctionalUtil.getParameters((Functional)declaration);
    }

    @Override
    @Ignore
    public FunctionDeclaration$impl $ceylon$language$meta$declaration$FunctionDeclaration$impl() {
        return null;
    }

    @Override
    @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.declaration::FunctionOrValueDeclaration>")
    public Sequential<? extends ceylon.language.meta.declaration.FunctionOrValueDeclaration> getParameterDeclarations(){
        return parameterList;
    }

    @Override
    @TypeInfo("ceylon.language.meta.declaration::FunctionOrValueDeclaration|ceylon.language::Null")
    public ceylon.language.meta.declaration.FunctionOrValueDeclaration getParameterDeclaration(@Name("name") String name){
        return FunctionalUtil.getParameterDeclaration(this.parameterList, name);
    }

    @Override
    @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.declaration::TypeParameter>")
    public Sequential<? extends ceylon.language.meta.declaration.TypeParameter> getTypeParameterDeclarations() {
        return typeParameters;
    }

    @Override
    @TypeInfo("ceylon.language.meta.declaration::TypeParameter|ceylon.language::Null")
    public ceylon.language.meta.declaration.TypeParameter getTypeParameterDeclaration(@Name("name") String name) {
        Iterator<? extends ceylon.language.meta.declaration.TypeParameter> iterator = typeParameters.iterator();
        Object it;
        while((it = iterator.next()) != finished_.get_()){
            ceylon.language.meta.declaration.TypeParameter tp = (ceylon.language.meta.declaration.TypeParameter) it;
            if(tp.getName().equals(name))
                return tp;
        }
        return null;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public <Return extends Object, Arguments extends Sequential<? extends Object>> ceylon.language.meta.model.Function<Return, Arguments> apply(TypeDescriptor $reifiedReturn,
            TypeDescriptor $reifiedArguments){
        return apply($reifiedReturn,$reifiedArguments,(Sequential)empty_.get_());
    }

    @Override
    @TypeInfo("ceylon.language.meta.model::Function<Return,Arguments>")
    @TypeParameters({
        @TypeParameter("Return"),
        @TypeParameter(value = "Arguments", satisfies = "ceylon.language::Sequential<ceylon.language::Anything>")
    })
    public <Return extends Object, Arguments extends Sequential<? extends Object>> ceylon.language.meta.model.Function<Return, Arguments> apply(
            @Ignore TypeDescriptor $reifiedReturn,
            @Ignore TypeDescriptor $reifiedArguments,
            @Name("typeArguments") @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.model::Type<ceylon.language::Anything>>") @Sequenced Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        if(!getToplevel())
            throw new ceylon.language.meta.model.TypeApplicationException("Cannot apply a member declaration with no container type: use memberApply");
        List<com.redhat.ceylon.compiler.typechecker.model.ProducedType> producedTypes = Metamodel.getProducedTypes(typeArguments);
        Metamodel.checkTypeArguments(null, declaration, producedTypes);
        com.redhat.ceylon.compiler.typechecker.model.ProducedReference appliedFunction = declaration.getProducedReference(null, producedTypes);
        TypeDescriptor reifiedType = Metamodel.getTypeDescriptorForFunction(appliedFunction);
        TypeDescriptor reifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.getUnit(), (Functional) declaration, appliedFunction);

        Metamodel.checkReifiedTypeArgument("apply", "Function<$1,$2>", Variance.OUT,
                declaration.getUnit().getCallableReturnType(appliedFunction.getFullType()), $reifiedReturn,
                Variance.IN, Metamodel.getProducedTypeForArguments(declaration.getUnit(), (Functional)declaration, appliedFunction), $reifiedArguments);
        return new AppliedFunction<Return,Arguments>(reifiedType, reifiedArguments, appliedFunction, this, null, null);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Ignore
    @Override
    public <Container, Return, Arguments extends Sequential<? extends Object>>
        ceylon.language.meta.model.Method<Container, Return, Arguments> memberApply(TypeDescriptor $reifiedContainer,
                                                                               TypeDescriptor $reifiedReturn,
                                                                               TypeDescriptor $reifiedArguments,
                                                                               ceylon.language.meta.model.Type<? extends Container> containerType){

        return this.<Container, Return, Arguments>memberApply($reifiedContainer,
                                                              $reifiedReturn,
                                                              $reifiedArguments,
                                                              containerType,
                                                              (Sequential)empty_.get_());
    }

    @TypeInfo("ceylon.language.meta.model::Method<Container,Return,Arguments>")
    @TypeParameters({
        @TypeParameter("Container"),
        @TypeParameter("Return"),
        @TypeParameter(value = "Arguments", satisfies = "ceylon.language::Sequential<ceylon.language::Anything>")
    })
    @Override
    public <Container, Return, Arguments extends Sequential<? extends Object>>
        ceylon.language.meta.model.Method<Container, Return, Arguments> memberApply(
                @Ignore TypeDescriptor $reifiedContainer,
                @Ignore TypeDescriptor $reifiedReturn,
                @Ignore TypeDescriptor $reifiedArguments,
                @Name("containerType") ceylon.language.meta.model.Type<? extends Container> containerType,
                @Name("typeArguments") @Sequenced Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        if(getToplevel())
            throw new ceylon.language.meta.model.TypeApplicationException("Cannot apply a toplevel declaration to a container type: use apply");
        return getAppliedMethod($reifiedContainer, $reifiedReturn, $reifiedArguments, typeArguments, containerType);
    }

    <Container, Type, Arguments extends ceylon.language.Sequential<? extends Object>>
    ceylon.language.meta.model.Method<Container, Type, Arguments> getAppliedMethod(@Ignore TypeDescriptor $reifiedContainer,
                                                                              @Ignore TypeDescriptor $reifiedType,
                                                                              @Ignore TypeDescriptor $reifiedArguments,
                                                                              Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments,
                                                                              ceylon.language.meta.model.Type<? extends Object> container){
        List<com.redhat.ceylon.compiler.typechecker.model.ProducedType> producedTypes = Metamodel.getProducedTypes(typeArguments);
        ProducedType containerType = Metamodel.getModel(container);
        Metamodel.checkQualifyingType(containerType, declaration);
        Metamodel.checkTypeArguments(containerType, declaration, producedTypes);
        // find the proper qualifying type
        ProducedType memberQualifyingType = containerType.getSupertype((TypeDeclaration) declaration.getContainer());
        final ProducedTypedReference appliedFunction = ((com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration)declaration).getProducedTypedReference(memberQualifyingType, producedTypes);
        TypeDescriptor reifiedType = Metamodel.getTypeDescriptorForFunction(appliedFunction);
        TypeDescriptor reifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.getUnit(), (Functional) declaration, appliedFunction);
        TypeDescriptor reifiedContainer = Metamodel.getTypeDescriptorForProducedType(containerType);

        Metamodel.checkReifiedTypeArgument("memberApply", "Method<$1,$2,$3>",
                Variance.IN, containerType, $reifiedContainer,
                Variance.OUT, appliedFunction.getType(), $reifiedType,
                Variance.IN, Metamodel.getProducedTypeForArguments(declaration.getUnit(), (Functional)declaration, appliedFunction), $reifiedArguments);

        return new AppliedMethod<Container, Type, Arguments>(reifiedContainer, reifiedType, reifiedArguments, appliedFunction, this, container);
    }

    @Override
    @TypeInfo("ceylon.language.meta.declaration::OpenType")
    public OpenType getOpenType() {
        return type;
    }

    @Override
    public boolean getAnnotation(){
        return declaration.isAnnotation();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> invoke$typeArguments(){
        return (ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public java.lang.Object invoke(){
        return invoke((ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_());
    }

    @Ignore
    @Override
    public java.lang.Object invoke(
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        return invoke(typeArguments, empty_.get_());
    }

    @TypeInfo("ceylon.language::Anything")
    @Override
    public java.lang.Object invoke(
            @Name("typeArguments") @Defaulted
            @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.model::Type<ceylon.language::Anything>>")
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments,
            @Name("arguments") @Sequenced @TypeInfo("ceylon.language::Sequential<ceylon.language::Anything>")
            ceylon.language.Sequential<?> arguments){
        return apply(Anything.$TypeDescriptor$, TypeDescriptor.NothingType, typeArguments).apply(arguments);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>
        memberInvoke$typeArguments(java.lang.Object container){
        return (ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_();
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Ignore
    @Override
    public java.lang.Object memberInvoke(java.lang.Object container){
        return memberInvoke(container, (ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>>)(Sequential)empty_.get_());
    }

    @Ignore
    @Override
    public java.lang.Object memberInvoke(
            java.lang.Object container,
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments){
        return memberInvoke(container, typeArguments, empty_.get_());
    }

    @SuppressWarnings("unchecked")
    @TypeInfo("ceylon.language::Anything")
    @Override
    public java.lang.Object memberInvoke(
            @Name("container") @TypeInfo("ceylon.language::Anything")
            java.lang.Object container,
            @Name("typeArguments") @Defaulted
            @TypeInfo("ceylon.language::Sequential<ceylon.language.meta.model::Type<ceylon.language::Anything>>")
            ceylon.language.Sequential<? extends ceylon.language.meta.model.Type<?>> typeArguments,
            @Name("arguments") @Sequenced @TypeInfo("ceylon.language::Sequential<ceylon.language::Anything>")
            ceylon.language.Sequential<?> arguments){
        ceylon.language.meta.model.Type<?> containerType = Metamodel.getAppliedMetamodel(Metamodel.getTypeDescriptor(container));
        return memberApply(TypeDescriptor.NothingType, Anything.$TypeDescriptor$, TypeDescriptor.NothingType,
                containerType, typeArguments).bind(container).apply(arguments);
    }

    @Override
    public int hashCode() {
        return Metamodel.hashCode(this, "function");
    }

    @Override
    public boolean equals(Object obj) {
        if(obj == null)
            return false;
        if(obj == this)
            return true;
        if(obj instanceof FreeFunction == false)
            return false;
        return Metamodel.equalsForSameType(this, (FreeFunction)obj);
    }

    @Override
    public String toString() {
        return "function "+super.toString();
    }

    @Ignore
    @Override
    public TypeDescriptor $getType$() {
        return $TypeDescriptor$;
    }

    @Ignore
    @Override
    public java.lang.annotation.Annotation[] $getJavaAnnotations$() {
        // FIXME: this could be a FunctionalParameter!
        return Metamodel.getJavaMethod((Method) declaration).getAnnotations();
    }
}


text:
#pragma once

#include <cstddef>

namespace Urho3D
{

/// Combine hash into result value.
inline void CombineHash(unsigned& result, unsigned hash)
{
    result ^= hash + 0x9e3779b9 + (result << 6) + (result >> 2);
}

/// Pointer hash function.
template <class T> unsigned MakeHash(T* value)
{
    return (unsigned)((size_t)value / sizeof(T));
}

/// Const pointer hash function.
template <class T> unsigned MakeHash(const T* value)
{
    return (unsigned)((size_t)value / sizeof(T));
}

/// Generic hash function.
template <class T> unsigned MakeHash(const T& value)
{
    return value.ToHash();
}

/// Void pointer hash function.
template <> inline unsigned MakeHash(void* value)
{
    return (unsigned)(size_t)value;
}

/// Const void pointer hash function.
template <> inline unsigned MakeHash(const void* value)
{
    return (unsigned)(size_t)value;
}

/// Long long hash function.
template <> inline unsigned MakeHash(const long long& value)
{
    return (unsigned)((value >> 32u) | (value & 0xffffffffu));
}

/// Unsigned long long hash function.
template <> inline unsigned MakeHash(const unsigned long long& value)
{
    return (unsigned)((value >> 32u) | (value & 0xffffffffu));
}

/// Int hash function.
template <> inline unsigned MakeHash(const int& value)
{
    return (unsigned)value;
}

/// Unsigned hash function.
template <> inline unsigned MakeHash(const unsigned& value)
{
    return value;
}

/// Short hash function.
template <> inline unsigned MakeHash(const short& value)
{
    return (unsigned)value;
}

/// Unsigned short hash function.
template <> inline unsigned MakeHash(const unsigned short& value)
{
    return value;
}

/// Char hash function.
template <> inline unsigned MakeHash(const char& value)
{
    return (unsigned)value;
}

/// Unsigned char hash function.
template <> inline unsigned MakeHash(const unsigned char& value)
{
    return value;
}

}