Search for non empty list inside a list using Java 8 features
I have a code fragment that I want to make more concise yet readable
using Java 8 features like lambdas/streams etc.
Basically, there is a list of items and each item has a list of errors.
If there is at least one item with at least one error, "failure" needs to be returned. If no items with any error, return "success".
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
for (Item item : optionalItemList.get()) {
Optional<List<Error>> optionalErrorList = Optional.ofNullable((item.getErrors()));
if(optionalErrorList.isPresent())
if (!optionalErrorList.get().isEmpty()) {
return "failure";
}
}
return "success";
java java-8 java-stream optional
New contributor
add a comment |
I have a code fragment that I want to make more concise yet readable
using Java 8 features like lambdas/streams etc.
Basically, there is a list of items and each item has a list of errors.
If there is at least one item with at least one error, "failure" needs to be returned. If no items with any error, return "success".
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
for (Item item : optionalItemList.get()) {
Optional<List<Error>> optionalErrorList = Optional.ofNullable((item.getErrors()));
if(optionalErrorList.isPresent())
if (!optionalErrorList.get().isEmpty()) {
return "failure";
}
}
return "success";
java java-8 java-stream optional
New contributor
add a comment |
I have a code fragment that I want to make more concise yet readable
using Java 8 features like lambdas/streams etc.
Basically, there is a list of items and each item has a list of errors.
If there is at least one item with at least one error, "failure" needs to be returned. If no items with any error, return "success".
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
for (Item item : optionalItemList.get()) {
Optional<List<Error>> optionalErrorList = Optional.ofNullable((item.getErrors()));
if(optionalErrorList.isPresent())
if (!optionalErrorList.get().isEmpty()) {
return "failure";
}
}
return "success";
java java-8 java-stream optional
New contributor
I have a code fragment that I want to make more concise yet readable
using Java 8 features like lambdas/streams etc.
Basically, there is a list of items and each item has a list of errors.
If there is at least one item with at least one error, "failure" needs to be returned. If no items with any error, return "success".
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
for (Item item : optionalItemList.get()) {
Optional<List<Error>> optionalErrorList = Optional.ofNullable((item.getErrors()));
if(optionalErrorList.isPresent())
if (!optionalErrorList.get().isEmpty()) {
return "failure";
}
}
return "success";
java java-8 java-stream optional
java java-8 java-stream optional
New contributor
New contributor
edited Jan 19 at 15:52
MC Emperor
8,214125388
8,214125388
New contributor
asked Jan 19 at 11:54
user10937286user10937286
412
412
New contributor
New contributor
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
Optional
is not meant to replace if
statements, but to be used as a return value of methods. So I think you'd better not use it for this task. You can use the ternary operator along with Stream.allMatch
instead:
return message.getItems() == null ||
message.getItems().stream()
.allMatch(i -> i.getErrors() == null || i.getErrors().isEmpty()) ?
"success" :
"failure";
On a side note, methods should never return null
collections. The absence of elements should be expressed by returning empty collections. This would have made your code a lot easier:
return message.getItems().stream().allMatch(i -> i.getErrors().isEmpty()) ?
"success" :
"failure";
3
+1 for "Optional is not meant to replace if statements" and "Return an empty collection instead of null." If I could upvote this twice, I would!
– Stuart Marks
Jan 19 at 20:37
add a comment |
You can use flatMap
to search a list within a list. I personally think that a List
should never be null
, instead it should be an empty list. If that's a guarantee, then the code could be this:
boolean hasError = message.getItems().stream()
.flatMap(t -> t.getErrors().stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Otherwise, the code becomes a little longer:
boolean hasError = Optional.ofNullable(message.getItems()).orElse(List.of()).stream()
.flatMap(t -> Optional.ofNullable(t.getErrors()).orElse(List.of()).stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Note that I could have also used .count() > 0
instead of .findAny().isPresent()
. But the disadvantage of the former is that it iterates over all errors, while the latter short-circuits if any error is found.
add a comment |
You can use anyMatch
for the iterative code as :
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
if (optionalItemList.get().stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty())) {
return "failure";
}
return "success";
or further simplify it as :
return Optional.ofNullable(message.getItems())
.filter(a -> a.stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty()))
.map(a -> "failure")
.orElse("success");
Review: Just check if there is a critical pair of braces missing in the question.
– nullpointer
Jan 19 at 13:41
Optional.ofNullable((item.getErrors()))
could be replaced withOptional.ofNullable(item.getErrors())
.
– MC Emperor
Jan 19 at 15:49
add a comment |
To me you have made it overly complex. Here's a much simpler way of doing it. Make sure your getItems()
method returns an empty list if there are no items to return, so that you can dispense with additional null checks as above. This approach is less error prone and leads to more readable code. If you can do the same for getErrors
method above, you can merely dispense with the filter(Objects::nonNull)
and that will further simplify the stream processing pipeline.
String errorPresent = message.getItems().stream()
.map(Item::getErrors).filter(Objects::nonNull)
.map(List::size).filter(s -> s > 0)
.findAny().map(ignored -> "failure")
.orElse("success");
Alternatively you may use the ternary operator to get this thing done.
String errorPresent = message.getItems().stream()
.map(Item::getErrors)
.filter(Objects::nonNull)
.anyMatch(e -> !e.isEmpty()) ? "failure" : "success";
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
user10937286 is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54266801%2fsearch-for-non-empty-list-inside-a-list-using-java-8-features%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Optional
is not meant to replace if
statements, but to be used as a return value of methods. So I think you'd better not use it for this task. You can use the ternary operator along with Stream.allMatch
instead:
return message.getItems() == null ||
message.getItems().stream()
.allMatch(i -> i.getErrors() == null || i.getErrors().isEmpty()) ?
"success" :
"failure";
On a side note, methods should never return null
collections. The absence of elements should be expressed by returning empty collections. This would have made your code a lot easier:
return message.getItems().stream().allMatch(i -> i.getErrors().isEmpty()) ?
"success" :
"failure";
3
+1 for "Optional is not meant to replace if statements" and "Return an empty collection instead of null." If I could upvote this twice, I would!
– Stuart Marks
Jan 19 at 20:37
add a comment |
Optional
is not meant to replace if
statements, but to be used as a return value of methods. So I think you'd better not use it for this task. You can use the ternary operator along with Stream.allMatch
instead:
return message.getItems() == null ||
message.getItems().stream()
.allMatch(i -> i.getErrors() == null || i.getErrors().isEmpty()) ?
"success" :
"failure";
On a side note, methods should never return null
collections. The absence of elements should be expressed by returning empty collections. This would have made your code a lot easier:
return message.getItems().stream().allMatch(i -> i.getErrors().isEmpty()) ?
"success" :
"failure";
3
+1 for "Optional is not meant to replace if statements" and "Return an empty collection instead of null." If I could upvote this twice, I would!
– Stuart Marks
Jan 19 at 20:37
add a comment |
Optional
is not meant to replace if
statements, but to be used as a return value of methods. So I think you'd better not use it for this task. You can use the ternary operator along with Stream.allMatch
instead:
return message.getItems() == null ||
message.getItems().stream()
.allMatch(i -> i.getErrors() == null || i.getErrors().isEmpty()) ?
"success" :
"failure";
On a side note, methods should never return null
collections. The absence of elements should be expressed by returning empty collections. This would have made your code a lot easier:
return message.getItems().stream().allMatch(i -> i.getErrors().isEmpty()) ?
"success" :
"failure";
Optional
is not meant to replace if
statements, but to be used as a return value of methods. So I think you'd better not use it for this task. You can use the ternary operator along with Stream.allMatch
instead:
return message.getItems() == null ||
message.getItems().stream()
.allMatch(i -> i.getErrors() == null || i.getErrors().isEmpty()) ?
"success" :
"failure";
On a side note, methods should never return null
collections. The absence of elements should be expressed by returning empty collections. This would have made your code a lot easier:
return message.getItems().stream().allMatch(i -> i.getErrors().isEmpty()) ?
"success" :
"failure";
edited Jan 19 at 20:56
answered Jan 19 at 15:44
Federico Peralta SchaffnerFederico Peralta Schaffner
22.6k43673
22.6k43673
3
+1 for "Optional is not meant to replace if statements" and "Return an empty collection instead of null." If I could upvote this twice, I would!
– Stuart Marks
Jan 19 at 20:37
add a comment |
3
+1 for "Optional is not meant to replace if statements" and "Return an empty collection instead of null." If I could upvote this twice, I would!
– Stuart Marks
Jan 19 at 20:37
3
3
+1 for "Optional is not meant to replace if statements" and "Return an empty collection instead of null." If I could upvote this twice, I would!
– Stuart Marks
Jan 19 at 20:37
+1 for "Optional is not meant to replace if statements" and "Return an empty collection instead of null." If I could upvote this twice, I would!
– Stuart Marks
Jan 19 at 20:37
add a comment |
You can use flatMap
to search a list within a list. I personally think that a List
should never be null
, instead it should be an empty list. If that's a guarantee, then the code could be this:
boolean hasError = message.getItems().stream()
.flatMap(t -> t.getErrors().stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Otherwise, the code becomes a little longer:
boolean hasError = Optional.ofNullable(message.getItems()).orElse(List.of()).stream()
.flatMap(t -> Optional.ofNullable(t.getErrors()).orElse(List.of()).stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Note that I could have also used .count() > 0
instead of .findAny().isPresent()
. But the disadvantage of the former is that it iterates over all errors, while the latter short-circuits if any error is found.
add a comment |
You can use flatMap
to search a list within a list. I personally think that a List
should never be null
, instead it should be an empty list. If that's a guarantee, then the code could be this:
boolean hasError = message.getItems().stream()
.flatMap(t -> t.getErrors().stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Otherwise, the code becomes a little longer:
boolean hasError = Optional.ofNullable(message.getItems()).orElse(List.of()).stream()
.flatMap(t -> Optional.ofNullable(t.getErrors()).orElse(List.of()).stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Note that I could have also used .count() > 0
instead of .findAny().isPresent()
. But the disadvantage of the former is that it iterates over all errors, while the latter short-circuits if any error is found.
add a comment |
You can use flatMap
to search a list within a list. I personally think that a List
should never be null
, instead it should be an empty list. If that's a guarantee, then the code could be this:
boolean hasError = message.getItems().stream()
.flatMap(t -> t.getErrors().stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Otherwise, the code becomes a little longer:
boolean hasError = Optional.ofNullable(message.getItems()).orElse(List.of()).stream()
.flatMap(t -> Optional.ofNullable(t.getErrors()).orElse(List.of()).stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Note that I could have also used .count() > 0
instead of .findAny().isPresent()
. But the disadvantage of the former is that it iterates over all errors, while the latter short-circuits if any error is found.
You can use flatMap
to search a list within a list. I personally think that a List
should never be null
, instead it should be an empty list. If that's a guarantee, then the code could be this:
boolean hasError = message.getItems().stream()
.flatMap(t -> t.getErrors().stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Otherwise, the code becomes a little longer:
boolean hasError = Optional.ofNullable(message.getItems()).orElse(List.of()).stream()
.flatMap(t -> Optional.ofNullable(t.getErrors()).orElse(List.of()).stream())
.findAny()
.isPresent();
return (hasError ? "success" : "failure");
Note that I could have also used .count() > 0
instead of .findAny().isPresent()
. But the disadvantage of the former is that it iterates over all errors, while the latter short-circuits if any error is found.
answered Jan 19 at 17:50
MC EmperorMC Emperor
8,214125388
8,214125388
add a comment |
add a comment |
You can use anyMatch
for the iterative code as :
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
if (optionalItemList.get().stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty())) {
return "failure";
}
return "success";
or further simplify it as :
return Optional.ofNullable(message.getItems())
.filter(a -> a.stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty()))
.map(a -> "failure")
.orElse("success");
Review: Just check if there is a critical pair of braces missing in the question.
– nullpointer
Jan 19 at 13:41
Optional.ofNullable((item.getErrors()))
could be replaced withOptional.ofNullable(item.getErrors())
.
– MC Emperor
Jan 19 at 15:49
add a comment |
You can use anyMatch
for the iterative code as :
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
if (optionalItemList.get().stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty())) {
return "failure";
}
return "success";
or further simplify it as :
return Optional.ofNullable(message.getItems())
.filter(a -> a.stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty()))
.map(a -> "failure")
.orElse("success");
Review: Just check if there is a critical pair of braces missing in the question.
– nullpointer
Jan 19 at 13:41
Optional.ofNullable((item.getErrors()))
could be replaced withOptional.ofNullable(item.getErrors())
.
– MC Emperor
Jan 19 at 15:49
add a comment |
You can use anyMatch
for the iterative code as :
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
if (optionalItemList.get().stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty())) {
return "failure";
}
return "success";
or further simplify it as :
return Optional.ofNullable(message.getItems())
.filter(a -> a.stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty()))
.map(a -> "failure")
.orElse("success");
You can use anyMatch
for the iterative code as :
Optional<List<Item>> optionalItemList = Optional.ofNullable(message.getItems());
if (optionalItemList.isPresent())
if (optionalItemList.get().stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty())) {
return "failure";
}
return "success";
or further simplify it as :
return Optional.ofNullable(message.getItems())
.filter(a -> a.stream()
.map(item -> Optional.ofNullable((item.getErrors())))
.filter(Optional::isPresent)
.anyMatch(optionalErrorList -> !optionalErrorList.get().isEmpty()))
.map(a -> "failure")
.orElse("success");
answered Jan 19 at 12:14
nullpointernullpointer
46.4k1199190
46.4k1199190
Review: Just check if there is a critical pair of braces missing in the question.
– nullpointer
Jan 19 at 13:41
Optional.ofNullable((item.getErrors()))
could be replaced withOptional.ofNullable(item.getErrors())
.
– MC Emperor
Jan 19 at 15:49
add a comment |
Review: Just check if there is a critical pair of braces missing in the question.
– nullpointer
Jan 19 at 13:41
Optional.ofNullable((item.getErrors()))
could be replaced withOptional.ofNullable(item.getErrors())
.
– MC Emperor
Jan 19 at 15:49
Review: Just check if there is a critical pair of braces missing in the question.
– nullpointer
Jan 19 at 13:41
Review: Just check if there is a critical pair of braces missing in the question.
– nullpointer
Jan 19 at 13:41
Optional.ofNullable((item.getErrors()))
could be replaced with Optional.ofNullable(item.getErrors())
.– MC Emperor
Jan 19 at 15:49
Optional.ofNullable((item.getErrors()))
could be replaced with Optional.ofNullable(item.getErrors())
.– MC Emperor
Jan 19 at 15:49
add a comment |
To me you have made it overly complex. Here's a much simpler way of doing it. Make sure your getItems()
method returns an empty list if there are no items to return, so that you can dispense with additional null checks as above. This approach is less error prone and leads to more readable code. If you can do the same for getErrors
method above, you can merely dispense with the filter(Objects::nonNull)
and that will further simplify the stream processing pipeline.
String errorPresent = message.getItems().stream()
.map(Item::getErrors).filter(Objects::nonNull)
.map(List::size).filter(s -> s > 0)
.findAny().map(ignored -> "failure")
.orElse("success");
Alternatively you may use the ternary operator to get this thing done.
String errorPresent = message.getItems().stream()
.map(Item::getErrors)
.filter(Objects::nonNull)
.anyMatch(e -> !e.isEmpty()) ? "failure" : "success";
add a comment |
To me you have made it overly complex. Here's a much simpler way of doing it. Make sure your getItems()
method returns an empty list if there are no items to return, so that you can dispense with additional null checks as above. This approach is less error prone and leads to more readable code. If you can do the same for getErrors
method above, you can merely dispense with the filter(Objects::nonNull)
and that will further simplify the stream processing pipeline.
String errorPresent = message.getItems().stream()
.map(Item::getErrors).filter(Objects::nonNull)
.map(List::size).filter(s -> s > 0)
.findAny().map(ignored -> "failure")
.orElse("success");
Alternatively you may use the ternary operator to get this thing done.
String errorPresent = message.getItems().stream()
.map(Item::getErrors)
.filter(Objects::nonNull)
.anyMatch(e -> !e.isEmpty()) ? "failure" : "success";
add a comment |
To me you have made it overly complex. Here's a much simpler way of doing it. Make sure your getItems()
method returns an empty list if there are no items to return, so that you can dispense with additional null checks as above. This approach is less error prone and leads to more readable code. If you can do the same for getErrors
method above, you can merely dispense with the filter(Objects::nonNull)
and that will further simplify the stream processing pipeline.
String errorPresent = message.getItems().stream()
.map(Item::getErrors).filter(Objects::nonNull)
.map(List::size).filter(s -> s > 0)
.findAny().map(ignored -> "failure")
.orElse("success");
Alternatively you may use the ternary operator to get this thing done.
String errorPresent = message.getItems().stream()
.map(Item::getErrors)
.filter(Objects::nonNull)
.anyMatch(e -> !e.isEmpty()) ? "failure" : "success";
To me you have made it overly complex. Here's a much simpler way of doing it. Make sure your getItems()
method returns an empty list if there are no items to return, so that you can dispense with additional null checks as above. This approach is less error prone and leads to more readable code. If you can do the same for getErrors
method above, you can merely dispense with the filter(Objects::nonNull)
and that will further simplify the stream processing pipeline.
String errorPresent = message.getItems().stream()
.map(Item::getErrors).filter(Objects::nonNull)
.map(List::size).filter(s -> s > 0)
.findAny().map(ignored -> "failure")
.orElse("success");
Alternatively you may use the ternary operator to get this thing done.
String errorPresent = message.getItems().stream()
.map(Item::getErrors)
.filter(Objects::nonNull)
.anyMatch(e -> !e.isEmpty()) ? "failure" : "success";
edited Jan 19 at 17:29
answered Jan 19 at 14:03
Ravindra RanwalaRavindra Ranwala
9,05031634
9,05031634
add a comment |
add a comment |
user10937286 is a new contributor. Be nice, and check out our Code of Conduct.
user10937286 is a new contributor. Be nice, and check out our Code of Conduct.
user10937286 is a new contributor. Be nice, and check out our Code of Conduct.
user10937286 is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54266801%2fsearch-for-non-empty-list-inside-a-list-using-java-8-features%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown